ARI - implement allowMultiple for parameters
[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_stasis</depend>
37         <support_level>core</support_level>
38  ***/
39
40 #include "asterisk.h"
41
42 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
43
44 #include "asterisk/app.h"
45 #include "asterisk/module.h"
46 #include "asterisk/stasis_app.h"
47 #include "ari/resource_channels.h"
48 #if defined(AST_DEVMODE)
49 #include "ari/ari_model_validators.h"
50 #endif
51
52 #define MAX_VALS 128
53
54 /*!
55  * \brief Parameter parsing callback for /channels.
56  * \param get_params GET parameters in the HTTP request.
57  * \param path_vars Path variables extracted from the request.
58  * \param headers HTTP headers.
59  * \param[out] response Response to the HTTP request.
60  */
61 static void ast_ari_get_channels_cb(
62         struct ast_variable *get_params, struct ast_variable *path_vars,
63         struct ast_variable *headers, struct ast_ari_response *response)
64 {
65         struct ast_get_channels_args args = {};
66 #if defined(AST_DEVMODE)
67         int is_valid;
68         int code;
69 #endif /* AST_DEVMODE */
70
71         ast_ari_get_channels(headers, &args, response);
72 #if defined(AST_DEVMODE)
73         code = response->response_code;
74
75         switch (code) {
76         case 0: /* Implementation is still a stub, or the code wasn't set */
77                 is_valid = response->message == NULL;
78                 break;
79         case 500: /* Internal Server Error */
80         case 501: /* Not Implemented */
81                 is_valid = 1;
82                 break;
83         default:
84                 if (200 <= code && code <= 299) {
85                         is_valid = ast_ari_validate_list(response->message,
86                                 ast_ari_validate_channel_fn());
87                 } else {
88                         ast_log(LOG_ERROR, "Invalid error response %d for /channels\n", code);
89                         is_valid = 0;
90                 }
91         }
92
93         if (!is_valid) {
94                 ast_log(LOG_ERROR, "Response validation failed for /channels\n");
95                 ast_ari_response_error(response, 500,
96                         "Internal Server Error", "Response validation failed");
97         }
98 #endif /* AST_DEVMODE */
99
100 fin: __attribute__((unused))
101         return;
102 }
103 /*!
104  * \brief Parameter parsing callback for /channels.
105  * \param get_params GET parameters in the HTTP request.
106  * \param path_vars Path variables extracted from the request.
107  * \param headers HTTP headers.
108  * \param[out] response Response to the HTTP request.
109  */
110 static void ast_ari_originate_cb(
111         struct ast_variable *get_params, struct ast_variable *path_vars,
112         struct ast_variable *headers, struct ast_ari_response *response)
113 {
114         struct ast_originate_args args = {};
115         struct ast_variable *i;
116 #if defined(AST_DEVMODE)
117         int is_valid;
118         int code;
119 #endif /* AST_DEVMODE */
120
121         for (i = get_params; i; i = i->next) {
122                 if (strcmp(i->name, "endpoint") == 0) {
123                         args.endpoint = (i->value);
124                 } else
125                 if (strcmp(i->name, "extension") == 0) {
126                         args.extension = (i->value);
127                 } else
128                 if (strcmp(i->name, "context") == 0) {
129                         args.context = (i->value);
130                 } else
131                 if (strcmp(i->name, "priority") == 0) {
132                         args.priority = atol(i->value);
133                 } else
134                 if (strcmp(i->name, "app") == 0) {
135                         args.app = (i->value);
136                 } else
137                 if (strcmp(i->name, "appArgs") == 0) {
138                         args.app_args = (i->value);
139                 } else
140                 if (strcmp(i->name, "callerId") == 0) {
141                         args.caller_id = (i->value);
142                 } else
143                 if (strcmp(i->name, "timeout") == 0) {
144                         args.timeout = atoi(i->value);
145                 } else
146                 {}
147         }
148         ast_ari_originate(headers, &args, response);
149 #if defined(AST_DEVMODE)
150         code = response->response_code;
151
152         switch (code) {
153         case 0: /* Implementation is still a stub, or the code wasn't set */
154                 is_valid = response->message == NULL;
155                 break;
156         case 500: /* Internal Server Error */
157         case 501: /* Not Implemented */
158         case 400: /* Invalid parameters for originating a channel. */
159                 is_valid = 1;
160                 break;
161         default:
162                 if (200 <= code && code <= 299) {
163                         is_valid = ast_ari_validate_void(
164                                 response->message);
165                 } else {
166                         ast_log(LOG_ERROR, "Invalid error response %d for /channels\n", code);
167                         is_valid = 0;
168                 }
169         }
170
171         if (!is_valid) {
172                 ast_log(LOG_ERROR, "Response validation failed for /channels\n");
173                 ast_ari_response_error(response, 500,
174                         "Internal Server Error", "Response validation failed");
175         }
176 #endif /* AST_DEVMODE */
177
178 fin: __attribute__((unused))
179         return;
180 }
181 /*!
182  * \brief Parameter parsing callback for /channels/{channelId}.
183  * \param get_params GET parameters in the HTTP request.
184  * \param path_vars Path variables extracted from the request.
185  * \param headers HTTP headers.
186  * \param[out] response Response to the HTTP request.
187  */
188 static void ast_ari_get_channel_cb(
189         struct ast_variable *get_params, struct ast_variable *path_vars,
190         struct ast_variable *headers, struct ast_ari_response *response)
191 {
192         struct ast_get_channel_args args = {};
193         struct ast_variable *i;
194 #if defined(AST_DEVMODE)
195         int is_valid;
196         int code;
197 #endif /* AST_DEVMODE */
198
199         for (i = path_vars; i; i = i->next) {
200                 if (strcmp(i->name, "channelId") == 0) {
201                         args.channel_id = (i->value);
202                 } else
203                 {}
204         }
205         ast_ari_get_channel(headers, &args, response);
206 #if defined(AST_DEVMODE)
207         code = response->response_code;
208
209         switch (code) {
210         case 0: /* Implementation is still a stub, or the code wasn't set */
211                 is_valid = response->message == NULL;
212                 break;
213         case 500: /* Internal Server Error */
214         case 501: /* Not Implemented */
215         case 404: /* Channel not found */
216                 is_valid = 1;
217                 break;
218         default:
219                 if (200 <= code && code <= 299) {
220                         is_valid = ast_ari_validate_channel(
221                                 response->message);
222                 } else {
223                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}\n", code);
224                         is_valid = 0;
225                 }
226         }
227
228         if (!is_valid) {
229                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}\n");
230                 ast_ari_response_error(response, 500,
231                         "Internal Server Error", "Response validation failed");
232         }
233 #endif /* AST_DEVMODE */
234
235 fin: __attribute__((unused))
236         return;
237 }
238 /*!
239  * \brief Parameter parsing callback for /channels/{channelId}.
240  * \param get_params GET parameters in the HTTP request.
241  * \param path_vars Path variables extracted from the request.
242  * \param headers HTTP headers.
243  * \param[out] response Response to the HTTP request.
244  */
245 static void ast_ari_delete_channel_cb(
246         struct ast_variable *get_params, struct ast_variable *path_vars,
247         struct ast_variable *headers, struct ast_ari_response *response)
248 {
249         struct ast_delete_channel_args args = {};
250         struct ast_variable *i;
251 #if defined(AST_DEVMODE)
252         int is_valid;
253         int code;
254 #endif /* AST_DEVMODE */
255
256         for (i = path_vars; i; i = i->next) {
257                 if (strcmp(i->name, "channelId") == 0) {
258                         args.channel_id = (i->value);
259                 } else
260                 {}
261         }
262         ast_ari_delete_channel(headers, &args, response);
263 #if defined(AST_DEVMODE)
264         code = response->response_code;
265
266         switch (code) {
267         case 0: /* Implementation is still a stub, or the code wasn't set */
268                 is_valid = response->message == NULL;
269                 break;
270         case 500: /* Internal Server Error */
271         case 501: /* Not Implemented */
272         case 404: /* Channel not found */
273                 is_valid = 1;
274                 break;
275         default:
276                 if (200 <= code && code <= 299) {
277                         is_valid = ast_ari_validate_void(
278                                 response->message);
279                 } else {
280                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}\n", code);
281                         is_valid = 0;
282                 }
283         }
284
285         if (!is_valid) {
286                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}\n");
287                 ast_ari_response_error(response, 500,
288                         "Internal Server Error", "Response validation failed");
289         }
290 #endif /* AST_DEVMODE */
291
292 fin: __attribute__((unused))
293         return;
294 }
295 /*!
296  * \brief Parameter parsing callback for /channels/{channelId}/dial.
297  * \param get_params GET parameters in the HTTP request.
298  * \param path_vars Path variables extracted from the request.
299  * \param headers HTTP headers.
300  * \param[out] response Response to the HTTP request.
301  */
302 static void ast_ari_dial_cb(
303         struct ast_variable *get_params, struct ast_variable *path_vars,
304         struct ast_variable *headers, struct ast_ari_response *response)
305 {
306         struct ast_dial_args args = {};
307         struct ast_variable *i;
308 #if defined(AST_DEVMODE)
309         int is_valid;
310         int code;
311 #endif /* AST_DEVMODE */
312
313         for (i = get_params; i; i = i->next) {
314                 if (strcmp(i->name, "endpoint") == 0) {
315                         args.endpoint = (i->value);
316                 } else
317                 if (strcmp(i->name, "extension") == 0) {
318                         args.extension = (i->value);
319                 } else
320                 if (strcmp(i->name, "context") == 0) {
321                         args.context = (i->value);
322                 } else
323                 if (strcmp(i->name, "timeout") == 0) {
324                         args.timeout = atoi(i->value);
325                 } else
326                 {}
327         }
328         for (i = path_vars; i; i = i->next) {
329                 if (strcmp(i->name, "channelId") == 0) {
330                         args.channel_id = (i->value);
331                 } else
332                 {}
333         }
334         ast_ari_dial(headers, &args, response);
335 #if defined(AST_DEVMODE)
336         code = response->response_code;
337
338         switch (code) {
339         case 0: /* Implementation is still a stub, or the code wasn't set */
340                 is_valid = response->message == NULL;
341                 break;
342         case 500: /* Internal Server Error */
343         case 501: /* Not Implemented */
344         case 404: /* Channel not found */
345         case 409: /* Channel not in a Stasis application */
346                 is_valid = 1;
347                 break;
348         default:
349                 if (200 <= code && code <= 299) {
350                         is_valid = ast_ari_validate_dialed(
351                                 response->message);
352                 } else {
353                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/dial\n", code);
354                         is_valid = 0;
355                 }
356         }
357
358         if (!is_valid) {
359                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/dial\n");
360                 ast_ari_response_error(response, 500,
361                         "Internal Server Error", "Response validation failed");
362         }
363 #endif /* AST_DEVMODE */
364
365 fin: __attribute__((unused))
366         return;
367 }
368 /*!
369  * \brief Parameter parsing callback for /channels/{channelId}/continue.
370  * \param get_params GET parameters in the HTTP request.
371  * \param path_vars Path variables extracted from the request.
372  * \param headers HTTP headers.
373  * \param[out] response Response to the HTTP request.
374  */
375 static void ast_ari_continue_in_dialplan_cb(
376         struct ast_variable *get_params, struct ast_variable *path_vars,
377         struct ast_variable *headers, struct ast_ari_response *response)
378 {
379         struct ast_continue_in_dialplan_args args = {};
380         struct ast_variable *i;
381 #if defined(AST_DEVMODE)
382         int is_valid;
383         int code;
384 #endif /* AST_DEVMODE */
385
386         for (i = get_params; i; i = i->next) {
387                 if (strcmp(i->name, "context") == 0) {
388                         args.context = (i->value);
389                 } else
390                 if (strcmp(i->name, "extension") == 0) {
391                         args.extension = (i->value);
392                 } else
393                 if (strcmp(i->name, "priority") == 0) {
394                         args.priority = atoi(i->value);
395                 } else
396                 {}
397         }
398         for (i = path_vars; i; i = i->next) {
399                 if (strcmp(i->name, "channelId") == 0) {
400                         args.channel_id = (i->value);
401                 } else
402                 {}
403         }
404         ast_ari_continue_in_dialplan(headers, &args, response);
405 #if defined(AST_DEVMODE)
406         code = response->response_code;
407
408         switch (code) {
409         case 0: /* Implementation is still a stub, or the code wasn't set */
410                 is_valid = response->message == NULL;
411                 break;
412         case 500: /* Internal Server Error */
413         case 501: /* Not Implemented */
414         case 404: /* Channel not found */
415         case 409: /* Channel not in a Stasis application */
416                 is_valid = 1;
417                 break;
418         default:
419                 if (200 <= code && code <= 299) {
420                         is_valid = ast_ari_validate_void(
421                                 response->message);
422                 } else {
423                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/continue\n", code);
424                         is_valid = 0;
425                 }
426         }
427
428         if (!is_valid) {
429                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/continue\n");
430                 ast_ari_response_error(response, 500,
431                         "Internal Server Error", "Response validation failed");
432         }
433 #endif /* AST_DEVMODE */
434
435 fin: __attribute__((unused))
436         return;
437 }
438 /*!
439  * \brief Parameter parsing callback for /channels/{channelId}/answer.
440  * \param get_params GET parameters in the HTTP request.
441  * \param path_vars Path variables extracted from the request.
442  * \param headers HTTP headers.
443  * \param[out] response Response to the HTTP request.
444  */
445 static void ast_ari_answer_channel_cb(
446         struct ast_variable *get_params, struct ast_variable *path_vars,
447         struct ast_variable *headers, struct ast_ari_response *response)
448 {
449         struct ast_answer_channel_args args = {};
450         struct ast_variable *i;
451 #if defined(AST_DEVMODE)
452         int is_valid;
453         int code;
454 #endif /* AST_DEVMODE */
455
456         for (i = path_vars; i; i = i->next) {
457                 if (strcmp(i->name, "channelId") == 0) {
458                         args.channel_id = (i->value);
459                 } else
460                 {}
461         }
462         ast_ari_answer_channel(headers, &args, response);
463 #if defined(AST_DEVMODE)
464         code = response->response_code;
465
466         switch (code) {
467         case 0: /* Implementation is still a stub, or the code wasn't set */
468                 is_valid = response->message == NULL;
469                 break;
470         case 500: /* Internal Server Error */
471         case 501: /* Not Implemented */
472         case 404: /* Channel not found */
473         case 409: /* Channel not in a Stasis application */
474                 is_valid = 1;
475                 break;
476         default:
477                 if (200 <= code && code <= 299) {
478                         is_valid = ast_ari_validate_void(
479                                 response->message);
480                 } else {
481                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/answer\n", code);
482                         is_valid = 0;
483                 }
484         }
485
486         if (!is_valid) {
487                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/answer\n");
488                 ast_ari_response_error(response, 500,
489                         "Internal Server Error", "Response validation failed");
490         }
491 #endif /* AST_DEVMODE */
492
493 fin: __attribute__((unused))
494         return;
495 }
496 /*!
497  * \brief Parameter parsing callback for /channels/{channelId}/mute.
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_mute_channel_cb(
504         struct ast_variable *get_params, struct ast_variable *path_vars,
505         struct ast_variable *headers, struct ast_ari_response *response)
506 {
507         struct ast_mute_channel_args args = {};
508         struct ast_variable *i;
509 #if defined(AST_DEVMODE)
510         int is_valid;
511         int code;
512 #endif /* AST_DEVMODE */
513
514         for (i = get_params; i; i = i->next) {
515                 if (strcmp(i->name, "direction") == 0) {
516                         args.direction = (i->value);
517                 } else
518                 {}
519         }
520         for (i = path_vars; i; i = i->next) {
521                 if (strcmp(i->name, "channelId") == 0) {
522                         args.channel_id = (i->value);
523                 } else
524                 {}
525         }
526         ast_ari_mute_channel(headers, &args, response);
527 #if defined(AST_DEVMODE)
528         code = response->response_code;
529
530         switch (code) {
531         case 0: /* Implementation is still a stub, or the code wasn't set */
532                 is_valid = response->message == NULL;
533                 break;
534         case 500: /* Internal Server Error */
535         case 501: /* Not Implemented */
536         case 404: /* Channel not found */
537         case 409: /* Channel not in a Stasis application */
538                 is_valid = 1;
539                 break;
540         default:
541                 if (200 <= code && code <= 299) {
542                         is_valid = ast_ari_validate_void(
543                                 response->message);
544                 } else {
545                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/mute\n", code);
546                         is_valid = 0;
547                 }
548         }
549
550         if (!is_valid) {
551                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/mute\n");
552                 ast_ari_response_error(response, 500,
553                         "Internal Server Error", "Response validation failed");
554         }
555 #endif /* AST_DEVMODE */
556
557 fin: __attribute__((unused))
558         return;
559 }
560 /*!
561  * \brief Parameter parsing callback for /channels/{channelId}/unmute.
562  * \param get_params GET parameters in the HTTP request.
563  * \param path_vars Path variables extracted from the request.
564  * \param headers HTTP headers.
565  * \param[out] response Response to the HTTP request.
566  */
567 static void ast_ari_unmute_channel_cb(
568         struct ast_variable *get_params, struct ast_variable *path_vars,
569         struct ast_variable *headers, struct ast_ari_response *response)
570 {
571         struct ast_unmute_channel_args args = {};
572         struct ast_variable *i;
573 #if defined(AST_DEVMODE)
574         int is_valid;
575         int code;
576 #endif /* AST_DEVMODE */
577
578         for (i = get_params; i; i = i->next) {
579                 if (strcmp(i->name, "direction") == 0) {
580                         args.direction = (i->value);
581                 } else
582                 {}
583         }
584         for (i = path_vars; i; i = i->next) {
585                 if (strcmp(i->name, "channelId") == 0) {
586                         args.channel_id = (i->value);
587                 } else
588                 {}
589         }
590         ast_ari_unmute_channel(headers, &args, response);
591 #if defined(AST_DEVMODE)
592         code = response->response_code;
593
594         switch (code) {
595         case 0: /* Implementation is still a stub, or the code wasn't set */
596                 is_valid = response->message == NULL;
597                 break;
598         case 500: /* Internal Server Error */
599         case 501: /* Not Implemented */
600         case 404: /* Channel not found */
601         case 409: /* Channel not in a Stasis application */
602                 is_valid = 1;
603                 break;
604         default:
605                 if (200 <= code && code <= 299) {
606                         is_valid = ast_ari_validate_void(
607                                 response->message);
608                 } else {
609                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/unmute\n", code);
610                         is_valid = 0;
611                 }
612         }
613
614         if (!is_valid) {
615                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/unmute\n");
616                 ast_ari_response_error(response, 500,
617                         "Internal Server Error", "Response validation failed");
618         }
619 #endif /* AST_DEVMODE */
620
621 fin: __attribute__((unused))
622         return;
623 }
624 /*!
625  * \brief Parameter parsing callback for /channels/{channelId}/hold.
626  * \param get_params GET parameters in the HTTP request.
627  * \param path_vars Path variables extracted from the request.
628  * \param headers HTTP headers.
629  * \param[out] response Response to the HTTP request.
630  */
631 static void ast_ari_hold_channel_cb(
632         struct ast_variable *get_params, struct ast_variable *path_vars,
633         struct ast_variable *headers, struct ast_ari_response *response)
634 {
635         struct ast_hold_channel_args args = {};
636         struct ast_variable *i;
637 #if defined(AST_DEVMODE)
638         int is_valid;
639         int code;
640 #endif /* AST_DEVMODE */
641
642         for (i = path_vars; i; i = i->next) {
643                 if (strcmp(i->name, "channelId") == 0) {
644                         args.channel_id = (i->value);
645                 } else
646                 {}
647         }
648         ast_ari_hold_channel(headers, &args, response);
649 #if defined(AST_DEVMODE)
650         code = response->response_code;
651
652         switch (code) {
653         case 0: /* Implementation is still a stub, or the code wasn't set */
654                 is_valid = response->message == NULL;
655                 break;
656         case 500: /* Internal Server Error */
657         case 501: /* Not Implemented */
658         case 404: /* Channel not found */
659         case 409: /* Channel not in a Stasis application */
660                 is_valid = 1;
661                 break;
662         default:
663                 if (200 <= code && code <= 299) {
664                         is_valid = ast_ari_validate_void(
665                                 response->message);
666                 } else {
667                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/hold\n", code);
668                         is_valid = 0;
669                 }
670         }
671
672         if (!is_valid) {
673                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/hold\n");
674                 ast_ari_response_error(response, 500,
675                         "Internal Server Error", "Response validation failed");
676         }
677 #endif /* AST_DEVMODE */
678
679 fin: __attribute__((unused))
680         return;
681 }
682 /*!
683  * \brief Parameter parsing callback for /channels/{channelId}/unhold.
684  * \param get_params GET parameters in the HTTP request.
685  * \param path_vars Path variables extracted from the request.
686  * \param headers HTTP headers.
687  * \param[out] response Response to the HTTP request.
688  */
689 static void ast_ari_unhold_channel_cb(
690         struct ast_variable *get_params, struct ast_variable *path_vars,
691         struct ast_variable *headers, struct ast_ari_response *response)
692 {
693         struct ast_unhold_channel_args args = {};
694         struct ast_variable *i;
695 #if defined(AST_DEVMODE)
696         int is_valid;
697         int code;
698 #endif /* AST_DEVMODE */
699
700         for (i = path_vars; i; i = i->next) {
701                 if (strcmp(i->name, "channelId") == 0) {
702                         args.channel_id = (i->value);
703                 } else
704                 {}
705         }
706         ast_ari_unhold_channel(headers, &args, response);
707 #if defined(AST_DEVMODE)
708         code = response->response_code;
709
710         switch (code) {
711         case 0: /* Implementation is still a stub, or the code wasn't set */
712                 is_valid = response->message == NULL;
713                 break;
714         case 500: /* Internal Server Error */
715         case 501: /* Not Implemented */
716         case 404: /* Channel not found */
717         case 409: /* Channel not in a Stasis application */
718                 is_valid = 1;
719                 break;
720         default:
721                 if (200 <= code && code <= 299) {
722                         is_valid = ast_ari_validate_void(
723                                 response->message);
724                 } else {
725                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/unhold\n", code);
726                         is_valid = 0;
727                 }
728         }
729
730         if (!is_valid) {
731                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/unhold\n");
732                 ast_ari_response_error(response, 500,
733                         "Internal Server Error", "Response validation failed");
734         }
735 #endif /* AST_DEVMODE */
736
737 fin: __attribute__((unused))
738         return;
739 }
740 /*!
741  * \brief Parameter parsing callback for /channels/{channelId}/mohstart.
742  * \param get_params GET parameters in the HTTP request.
743  * \param path_vars Path variables extracted from the request.
744  * \param headers HTTP headers.
745  * \param[out] response Response to the HTTP request.
746  */
747 static void ast_ari_moh_start_channel_cb(
748         struct ast_variable *get_params, struct ast_variable *path_vars,
749         struct ast_variable *headers, struct ast_ari_response *response)
750 {
751         struct ast_moh_start_channel_args args = {};
752         struct ast_variable *i;
753 #if defined(AST_DEVMODE)
754         int is_valid;
755         int code;
756 #endif /* AST_DEVMODE */
757
758         for (i = get_params; i; i = i->next) {
759                 if (strcmp(i->name, "mohClass") == 0) {
760                         args.moh_class = (i->value);
761                 } else
762                 {}
763         }
764         for (i = path_vars; i; i = i->next) {
765                 if (strcmp(i->name, "channelId") == 0) {
766                         args.channel_id = (i->value);
767                 } else
768                 {}
769         }
770         ast_ari_moh_start_channel(headers, &args, response);
771 #if defined(AST_DEVMODE)
772         code = response->response_code;
773
774         switch (code) {
775         case 0: /* Implementation is still a stub, or the code wasn't set */
776                 is_valid = response->message == NULL;
777                 break;
778         case 500: /* Internal Server Error */
779         case 501: /* Not Implemented */
780         case 404: /* Channel not found */
781         case 409: /* Channel not in a Stasis application */
782                 is_valid = 1;
783                 break;
784         default:
785                 if (200 <= code && code <= 299) {
786                         is_valid = ast_ari_validate_void(
787                                 response->message);
788                 } else {
789                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/mohstart\n", code);
790                         is_valid = 0;
791                 }
792         }
793
794         if (!is_valid) {
795                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/mohstart\n");
796                 ast_ari_response_error(response, 500,
797                         "Internal Server Error", "Response validation failed");
798         }
799 #endif /* AST_DEVMODE */
800
801 fin: __attribute__((unused))
802         return;
803 }
804 /*!
805  * \brief Parameter parsing callback for /channels/{channelId}/mohstop.
806  * \param get_params GET parameters in the HTTP request.
807  * \param path_vars Path variables extracted from the request.
808  * \param headers HTTP headers.
809  * \param[out] response Response to the HTTP request.
810  */
811 static void ast_ari_moh_stop_channel_cb(
812         struct ast_variable *get_params, struct ast_variable *path_vars,
813         struct ast_variable *headers, struct ast_ari_response *response)
814 {
815         struct ast_moh_stop_channel_args args = {};
816         struct ast_variable *i;
817 #if defined(AST_DEVMODE)
818         int is_valid;
819         int code;
820 #endif /* AST_DEVMODE */
821
822         for (i = path_vars; i; i = i->next) {
823                 if (strcmp(i->name, "channelId") == 0) {
824                         args.channel_id = (i->value);
825                 } else
826                 {}
827         }
828         ast_ari_moh_stop_channel(headers, &args, response);
829 #if defined(AST_DEVMODE)
830         code = response->response_code;
831
832         switch (code) {
833         case 0: /* Implementation is still a stub, or the code wasn't set */
834                 is_valid = response->message == NULL;
835                 break;
836         case 500: /* Internal Server Error */
837         case 501: /* Not Implemented */
838         case 404: /* Channel not found */
839         case 409: /* Channel not in a Stasis application */
840                 is_valid = 1;
841                 break;
842         default:
843                 if (200 <= code && code <= 299) {
844                         is_valid = ast_ari_validate_void(
845                                 response->message);
846                 } else {
847                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/mohstop\n", code);
848                         is_valid = 0;
849                 }
850         }
851
852         if (!is_valid) {
853                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/mohstop\n");
854                 ast_ari_response_error(response, 500,
855                         "Internal Server Error", "Response validation failed");
856         }
857 #endif /* AST_DEVMODE */
858
859 fin: __attribute__((unused))
860         return;
861 }
862 /*!
863  * \brief Parameter parsing callback for /channels/{channelId}/play.
864  * \param get_params GET parameters in the HTTP request.
865  * \param path_vars Path variables extracted from the request.
866  * \param headers HTTP headers.
867  * \param[out] response Response to the HTTP request.
868  */
869 static void ast_ari_play_on_channel_cb(
870         struct ast_variable *get_params, struct ast_variable *path_vars,
871         struct ast_variable *headers, struct ast_ari_response *response)
872 {
873         struct ast_play_on_channel_args args = {};
874         struct ast_variable *i;
875 #if defined(AST_DEVMODE)
876         int is_valid;
877         int code;
878 #endif /* AST_DEVMODE */
879
880         for (i = get_params; i; i = i->next) {
881                 if (strcmp(i->name, "media") == 0) {
882                         args.media = (i->value);
883                 } else
884                 if (strcmp(i->name, "lang") == 0) {
885                         args.lang = (i->value);
886                 } else
887                 if (strcmp(i->name, "offsetms") == 0) {
888                         args.offsetms = atoi(i->value);
889                 } else
890                 if (strcmp(i->name, "skipms") == 0) {
891                         args.skipms = atoi(i->value);
892                 } else
893                 {}
894         }
895         for (i = path_vars; i; i = i->next) {
896                 if (strcmp(i->name, "channelId") == 0) {
897                         args.channel_id = (i->value);
898                 } else
899                 {}
900         }
901         ast_ari_play_on_channel(headers, &args, response);
902 #if defined(AST_DEVMODE)
903         code = response->response_code;
904
905         switch (code) {
906         case 0: /* Implementation is still a stub, or the code wasn't set */
907                 is_valid = response->message == NULL;
908                 break;
909         case 500: /* Internal Server Error */
910         case 501: /* Not Implemented */
911         case 404: /* Channel not found */
912         case 409: /* Channel not in a Stasis application */
913                 is_valid = 1;
914                 break;
915         default:
916                 if (200 <= code && code <= 299) {
917                         is_valid = ast_ari_validate_playback(
918                                 response->message);
919                 } else {
920                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/play\n", code);
921                         is_valid = 0;
922                 }
923         }
924
925         if (!is_valid) {
926                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/play\n");
927                 ast_ari_response_error(response, 500,
928                         "Internal Server Error", "Response validation failed");
929         }
930 #endif /* AST_DEVMODE */
931
932 fin: __attribute__((unused))
933         return;
934 }
935 /*!
936  * \brief Parameter parsing callback for /channels/{channelId}/record.
937  * \param get_params GET parameters in the HTTP request.
938  * \param path_vars Path variables extracted from the request.
939  * \param headers HTTP headers.
940  * \param[out] response Response to the HTTP request.
941  */
942 static void ast_ari_record_channel_cb(
943         struct ast_variable *get_params, struct ast_variable *path_vars,
944         struct ast_variable *headers, struct ast_ari_response *response)
945 {
946         struct ast_record_channel_args args = {};
947         struct ast_variable *i;
948 #if defined(AST_DEVMODE)
949         int is_valid;
950         int code;
951 #endif /* AST_DEVMODE */
952
953         for (i = get_params; i; i = i->next) {
954                 if (strcmp(i->name, "name") == 0) {
955                         args.name = (i->value);
956                 } else
957                 if (strcmp(i->name, "format") == 0) {
958                         args.format = (i->value);
959                 } else
960                 if (strcmp(i->name, "maxDurationSeconds") == 0) {
961                         args.max_duration_seconds = atoi(i->value);
962                 } else
963                 if (strcmp(i->name, "maxSilenceSeconds") == 0) {
964                         args.max_silence_seconds = atoi(i->value);
965                 } else
966                 if (strcmp(i->name, "ifExists") == 0) {
967                         args.if_exists = (i->value);
968                 } else
969                 if (strcmp(i->name, "beep") == 0) {
970                         args.beep = ast_true(i->value);
971                 } else
972                 if (strcmp(i->name, "terminateOn") == 0) {
973                         args.terminate_on = (i->value);
974                 } else
975                 {}
976         }
977         for (i = path_vars; i; i = i->next) {
978                 if (strcmp(i->name, "channelId") == 0) {
979                         args.channel_id = (i->value);
980                 } else
981                 {}
982         }
983         ast_ari_record_channel(headers, &args, response);
984 #if defined(AST_DEVMODE)
985         code = response->response_code;
986
987         switch (code) {
988         case 0: /* Implementation is still a stub, or the code wasn't set */
989                 is_valid = response->message == NULL;
990                 break;
991         case 500: /* Internal Server Error */
992         case 501: /* Not Implemented */
993         case 400: /* Invalid parameters */
994         case 404: /* Channel not found */
995         case 409: /* Channel is not in a Stasis application; the channel is currently bridged with other channels; A recording with the same name is currently in progress. */
996                 is_valid = 1;
997                 break;
998         default:
999                 if (200 <= code && code <= 299) {
1000                         is_valid = ast_ari_validate_live_recording(
1001                                 response->message);
1002                 } else {
1003                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/record\n", code);
1004                         is_valid = 0;
1005                 }
1006         }
1007
1008         if (!is_valid) {
1009                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/record\n");
1010                 ast_ari_response_error(response, 500,
1011                         "Internal Server Error", "Response validation failed");
1012         }
1013 #endif /* AST_DEVMODE */
1014
1015 fin: __attribute__((unused))
1016         return;
1017 }
1018 /*!
1019  * \brief Parameter parsing callback for /channels/{channelId}/variable.
1020  * \param get_params GET parameters in the HTTP request.
1021  * \param path_vars Path variables extracted from the request.
1022  * \param headers HTTP headers.
1023  * \param[out] response Response to the HTTP request.
1024  */
1025 static void ast_ari_get_channel_var_cb(
1026         struct ast_variable *get_params, struct ast_variable *path_vars,
1027         struct ast_variable *headers, struct ast_ari_response *response)
1028 {
1029         struct ast_get_channel_var_args args = {};
1030         struct ast_variable *i;
1031 #if defined(AST_DEVMODE)
1032         int is_valid;
1033         int code;
1034 #endif /* AST_DEVMODE */
1035
1036         for (i = get_params; i; i = i->next) {
1037                 if (strcmp(i->name, "variable") == 0) {
1038                         args.variable = (i->value);
1039                 } else
1040                 {}
1041         }
1042         for (i = path_vars; i; i = i->next) {
1043                 if (strcmp(i->name, "channelId") == 0) {
1044                         args.channel_id = (i->value);
1045                 } else
1046                 {}
1047         }
1048         ast_ari_get_channel_var(headers, &args, response);
1049 #if defined(AST_DEVMODE)
1050         code = response->response_code;
1051
1052         switch (code) {
1053         case 0: /* Implementation is still a stub, or the code wasn't set */
1054                 is_valid = response->message == NULL;
1055                 break;
1056         case 500: /* Internal Server Error */
1057         case 501: /* Not Implemented */
1058         case 404: /* Channel not found */
1059         case 409: /* Channel not in a Stasis application */
1060                 is_valid = 1;
1061                 break;
1062         default:
1063                 if (200 <= code && code <= 299) {
1064                         is_valid = ast_ari_validate_variable(
1065                                 response->message);
1066                 } else {
1067                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/variable\n", code);
1068                         is_valid = 0;
1069                 }
1070         }
1071
1072         if (!is_valid) {
1073                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/variable\n");
1074                 ast_ari_response_error(response, 500,
1075                         "Internal Server Error", "Response validation failed");
1076         }
1077 #endif /* AST_DEVMODE */
1078
1079 fin: __attribute__((unused))
1080         return;
1081 }
1082 /*!
1083  * \brief Parameter parsing callback for /channels/{channelId}/variable.
1084  * \param get_params GET parameters in the HTTP request.
1085  * \param path_vars Path variables extracted from the request.
1086  * \param headers HTTP headers.
1087  * \param[out] response Response to the HTTP request.
1088  */
1089 static void ast_ari_set_channel_var_cb(
1090         struct ast_variable *get_params, struct ast_variable *path_vars,
1091         struct ast_variable *headers, struct ast_ari_response *response)
1092 {
1093         struct ast_set_channel_var_args args = {};
1094         struct ast_variable *i;
1095 #if defined(AST_DEVMODE)
1096         int is_valid;
1097         int code;
1098 #endif /* AST_DEVMODE */
1099
1100         for (i = get_params; i; i = i->next) {
1101                 if (strcmp(i->name, "variable") == 0) {
1102                         args.variable = (i->value);
1103                 } else
1104                 if (strcmp(i->name, "value") == 0) {
1105                         args.value = (i->value);
1106                 } else
1107                 {}
1108         }
1109         for (i = path_vars; i; i = i->next) {
1110                 if (strcmp(i->name, "channelId") == 0) {
1111                         args.channel_id = (i->value);
1112                 } else
1113                 {}
1114         }
1115         ast_ari_set_channel_var(headers, &args, response);
1116 #if defined(AST_DEVMODE)
1117         code = response->response_code;
1118
1119         switch (code) {
1120         case 0: /* Implementation is still a stub, or the code wasn't set */
1121                 is_valid = response->message == NULL;
1122                 break;
1123         case 500: /* Internal Server Error */
1124         case 501: /* Not Implemented */
1125         case 404: /* Channel not found */
1126         case 409: /* Channel not in a Stasis application */
1127                 is_valid = 1;
1128                 break;
1129         default:
1130                 if (200 <= code && code <= 299) {
1131                         is_valid = ast_ari_validate_void(
1132                                 response->message);
1133                 } else {
1134                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/variable\n", code);
1135                         is_valid = 0;
1136                 }
1137         }
1138
1139         if (!is_valid) {
1140                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/variable\n");
1141                 ast_ari_response_error(response, 500,
1142                         "Internal Server Error", "Response validation failed");
1143         }
1144 #endif /* AST_DEVMODE */
1145
1146 fin: __attribute__((unused))
1147         return;
1148 }
1149
1150 /*! \brief REST handler for /api-docs/channels.{format} */
1151 static struct stasis_rest_handlers channels_channelId_dial = {
1152         .path_segment = "dial",
1153         .callbacks = {
1154                 [AST_HTTP_POST] = ast_ari_dial_cb,
1155         },
1156         .num_children = 0,
1157         .children = {  }
1158 };
1159 /*! \brief REST handler for /api-docs/channels.{format} */
1160 static struct stasis_rest_handlers channels_channelId_continue = {
1161         .path_segment = "continue",
1162         .callbacks = {
1163                 [AST_HTTP_POST] = ast_ari_continue_in_dialplan_cb,
1164         },
1165         .num_children = 0,
1166         .children = {  }
1167 };
1168 /*! \brief REST handler for /api-docs/channels.{format} */
1169 static struct stasis_rest_handlers channels_channelId_answer = {
1170         .path_segment = "answer",
1171         .callbacks = {
1172                 [AST_HTTP_POST] = ast_ari_answer_channel_cb,
1173         },
1174         .num_children = 0,
1175         .children = {  }
1176 };
1177 /*! \brief REST handler for /api-docs/channels.{format} */
1178 static struct stasis_rest_handlers channels_channelId_mute = {
1179         .path_segment = "mute",
1180         .callbacks = {
1181                 [AST_HTTP_POST] = ast_ari_mute_channel_cb,
1182         },
1183         .num_children = 0,
1184         .children = {  }
1185 };
1186 /*! \brief REST handler for /api-docs/channels.{format} */
1187 static struct stasis_rest_handlers channels_channelId_unmute = {
1188         .path_segment = "unmute",
1189         .callbacks = {
1190                 [AST_HTTP_POST] = ast_ari_unmute_channel_cb,
1191         },
1192         .num_children = 0,
1193         .children = {  }
1194 };
1195 /*! \brief REST handler for /api-docs/channels.{format} */
1196 static struct stasis_rest_handlers channels_channelId_hold = {
1197         .path_segment = "hold",
1198         .callbacks = {
1199                 [AST_HTTP_POST] = ast_ari_hold_channel_cb,
1200         },
1201         .num_children = 0,
1202         .children = {  }
1203 };
1204 /*! \brief REST handler for /api-docs/channels.{format} */
1205 static struct stasis_rest_handlers channels_channelId_unhold = {
1206         .path_segment = "unhold",
1207         .callbacks = {
1208                 [AST_HTTP_POST] = ast_ari_unhold_channel_cb,
1209         },
1210         .num_children = 0,
1211         .children = {  }
1212 };
1213 /*! \brief REST handler for /api-docs/channels.{format} */
1214 static struct stasis_rest_handlers channels_channelId_mohstart = {
1215         .path_segment = "mohstart",
1216         .callbacks = {
1217                 [AST_HTTP_POST] = ast_ari_moh_start_channel_cb,
1218         },
1219         .num_children = 0,
1220         .children = {  }
1221 };
1222 /*! \brief REST handler for /api-docs/channels.{format} */
1223 static struct stasis_rest_handlers channels_channelId_mohstop = {
1224         .path_segment = "mohstop",
1225         .callbacks = {
1226                 [AST_HTTP_POST] = ast_ari_moh_stop_channel_cb,
1227         },
1228         .num_children = 0,
1229         .children = {  }
1230 };
1231 /*! \brief REST handler for /api-docs/channels.{format} */
1232 static struct stasis_rest_handlers channels_channelId_play = {
1233         .path_segment = "play",
1234         .callbacks = {
1235                 [AST_HTTP_POST] = ast_ari_play_on_channel_cb,
1236         },
1237         .num_children = 0,
1238         .children = {  }
1239 };
1240 /*! \brief REST handler for /api-docs/channels.{format} */
1241 static struct stasis_rest_handlers channels_channelId_record = {
1242         .path_segment = "record",
1243         .callbacks = {
1244                 [AST_HTTP_POST] = ast_ari_record_channel_cb,
1245         },
1246         .num_children = 0,
1247         .children = {  }
1248 };
1249 /*! \brief REST handler for /api-docs/channels.{format} */
1250 static struct stasis_rest_handlers channels_channelId_variable = {
1251         .path_segment = "variable",
1252         .callbacks = {
1253                 [AST_HTTP_GET] = ast_ari_get_channel_var_cb,
1254                 [AST_HTTP_POST] = ast_ari_set_channel_var_cb,
1255         },
1256         .num_children = 0,
1257         .children = {  }
1258 };
1259 /*! \brief REST handler for /api-docs/channels.{format} */
1260 static struct stasis_rest_handlers channels_channelId = {
1261         .path_segment = "channelId",
1262         .is_wildcard = 1,
1263         .callbacks = {
1264                 [AST_HTTP_GET] = ast_ari_get_channel_cb,
1265                 [AST_HTTP_DELETE] = ast_ari_delete_channel_cb,
1266         },
1267         .num_children = 12,
1268         .children = { &channels_channelId_dial,&channels_channelId_continue,&channels_channelId_answer,&channels_channelId_mute,&channels_channelId_unmute,&channels_channelId_hold,&channels_channelId_unhold,&channels_channelId_mohstart,&channels_channelId_mohstop,&channels_channelId_play,&channels_channelId_record,&channels_channelId_variable, }
1269 };
1270 /*! \brief REST handler for /api-docs/channels.{format} */
1271 static struct stasis_rest_handlers channels = {
1272         .path_segment = "channels",
1273         .callbacks = {
1274                 [AST_HTTP_GET] = ast_ari_get_channels_cb,
1275                 [AST_HTTP_POST] = ast_ari_originate_cb,
1276         },
1277         .num_children = 1,
1278         .children = { &channels_channelId, }
1279 };
1280
1281 static int load_module(void)
1282 {
1283         int res = 0;
1284         stasis_app_ref();
1285         res |= ast_ari_add_handler(&channels);
1286         return res;
1287 }
1288
1289 static int unload_module(void)
1290 {
1291         ast_ari_remove_handler(&channels);
1292         stasis_app_unref();
1293         return 0;
1294 }
1295
1296 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "RESTful API module - Channel resources",
1297         .load = load_module,
1298         .unload = unload_module,
1299         .nonoptreq = "res_ari,res_stasis",
1300         );