82ec3b6bc3853a32fc83124f6821bce12496bd5e
[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_channel(
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}/continue.
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_continue_in_dialplan_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_continue_in_dialplan_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, "context") == 0) {
315                         args.context = (i->value);
316                 } else
317                 if (strcmp(i->name, "extension") == 0) {
318                         args.extension = (i->value);
319                 } else
320                 if (strcmp(i->name, "priority") == 0) {
321                         args.priority = atoi(i->value);
322                 } else
323                 {}
324         }
325         for (i = path_vars; i; i = i->next) {
326                 if (strcmp(i->name, "channelId") == 0) {
327                         args.channel_id = (i->value);
328                 } else
329                 {}
330         }
331         ast_ari_continue_in_dialplan(headers, &args, response);
332 #if defined(AST_DEVMODE)
333         code = response->response_code;
334
335         switch (code) {
336         case 0: /* Implementation is still a stub, or the code wasn't set */
337                 is_valid = response->message == NULL;
338                 break;
339         case 500: /* Internal Server Error */
340         case 501: /* Not Implemented */
341         case 404: /* Channel not found */
342         case 409: /* Channel not in a Stasis application */
343                 is_valid = 1;
344                 break;
345         default:
346                 if (200 <= code && code <= 299) {
347                         is_valid = ast_ari_validate_void(
348                                 response->message);
349                 } else {
350                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/continue\n", code);
351                         is_valid = 0;
352                 }
353         }
354
355         if (!is_valid) {
356                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/continue\n");
357                 ast_ari_response_error(response, 500,
358                         "Internal Server Error", "Response validation failed");
359         }
360 #endif /* AST_DEVMODE */
361
362 fin: __attribute__((unused))
363         return;
364 }
365 /*!
366  * \brief Parameter parsing callback for /channels/{channelId}/answer.
367  * \param get_params GET parameters in the HTTP request.
368  * \param path_vars Path variables extracted from the request.
369  * \param headers HTTP headers.
370  * \param[out] response Response to the HTTP request.
371  */
372 static void ast_ari_answer_channel_cb(
373         struct ast_variable *get_params, struct ast_variable *path_vars,
374         struct ast_variable *headers, struct ast_ari_response *response)
375 {
376         struct ast_answer_channel_args args = {};
377         struct ast_variable *i;
378 #if defined(AST_DEVMODE)
379         int is_valid;
380         int code;
381 #endif /* AST_DEVMODE */
382
383         for (i = path_vars; i; i = i->next) {
384                 if (strcmp(i->name, "channelId") == 0) {
385                         args.channel_id = (i->value);
386                 } else
387                 {}
388         }
389         ast_ari_answer_channel(headers, &args, response);
390 #if defined(AST_DEVMODE)
391         code = response->response_code;
392
393         switch (code) {
394         case 0: /* Implementation is still a stub, or the code wasn't set */
395                 is_valid = response->message == NULL;
396                 break;
397         case 500: /* Internal Server Error */
398         case 501: /* Not Implemented */
399         case 404: /* Channel not found */
400         case 409: /* Channel not in a Stasis application */
401                 is_valid = 1;
402                 break;
403         default:
404                 if (200 <= code && code <= 299) {
405                         is_valid = ast_ari_validate_void(
406                                 response->message);
407                 } else {
408                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/answer\n", code);
409                         is_valid = 0;
410                 }
411         }
412
413         if (!is_valid) {
414                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/answer\n");
415                 ast_ari_response_error(response, 500,
416                         "Internal Server Error", "Response validation failed");
417         }
418 #endif /* AST_DEVMODE */
419
420 fin: __attribute__((unused))
421         return;
422 }
423 /*!
424  * \brief Parameter parsing callback for /channels/{channelId}/mute.
425  * \param get_params GET parameters in the HTTP request.
426  * \param path_vars Path variables extracted from the request.
427  * \param headers HTTP headers.
428  * \param[out] response Response to the HTTP request.
429  */
430 static void ast_ari_mute_channel_cb(
431         struct ast_variable *get_params, struct ast_variable *path_vars,
432         struct ast_variable *headers, struct ast_ari_response *response)
433 {
434         struct ast_mute_channel_args args = {};
435         struct ast_variable *i;
436 #if defined(AST_DEVMODE)
437         int is_valid;
438         int code;
439 #endif /* AST_DEVMODE */
440
441         for (i = get_params; i; i = i->next) {
442                 if (strcmp(i->name, "direction") == 0) {
443                         args.direction = (i->value);
444                 } else
445                 {}
446         }
447         for (i = path_vars; i; i = i->next) {
448                 if (strcmp(i->name, "channelId") == 0) {
449                         args.channel_id = (i->value);
450                 } else
451                 {}
452         }
453         ast_ari_mute_channel(headers, &args, response);
454 #if defined(AST_DEVMODE)
455         code = response->response_code;
456
457         switch (code) {
458         case 0: /* Implementation is still a stub, or the code wasn't set */
459                 is_valid = response->message == NULL;
460                 break;
461         case 500: /* Internal Server Error */
462         case 501: /* Not Implemented */
463         case 404: /* Channel not found */
464         case 409: /* Channel not in a Stasis application */
465                 is_valid = 1;
466                 break;
467         default:
468                 if (200 <= code && code <= 299) {
469                         is_valid = ast_ari_validate_void(
470                                 response->message);
471                 } else {
472                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/mute\n", code);
473                         is_valid = 0;
474                 }
475         }
476
477         if (!is_valid) {
478                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/mute\n");
479                 ast_ari_response_error(response, 500,
480                         "Internal Server Error", "Response validation failed");
481         }
482 #endif /* AST_DEVMODE */
483
484 fin: __attribute__((unused))
485         return;
486 }
487 /*!
488  * \brief Parameter parsing callback for /channels/{channelId}/unmute.
489  * \param get_params GET parameters in the HTTP request.
490  * \param path_vars Path variables extracted from the request.
491  * \param headers HTTP headers.
492  * \param[out] response Response to the HTTP request.
493  */
494 static void ast_ari_unmute_channel_cb(
495         struct ast_variable *get_params, struct ast_variable *path_vars,
496         struct ast_variable *headers, struct ast_ari_response *response)
497 {
498         struct ast_unmute_channel_args args = {};
499         struct ast_variable *i;
500 #if defined(AST_DEVMODE)
501         int is_valid;
502         int code;
503 #endif /* AST_DEVMODE */
504
505         for (i = get_params; i; i = i->next) {
506                 if (strcmp(i->name, "direction") == 0) {
507                         args.direction = (i->value);
508                 } else
509                 {}
510         }
511         for (i = path_vars; i; i = i->next) {
512                 if (strcmp(i->name, "channelId") == 0) {
513                         args.channel_id = (i->value);
514                 } else
515                 {}
516         }
517         ast_ari_unmute_channel(headers, &args, response);
518 #if defined(AST_DEVMODE)
519         code = response->response_code;
520
521         switch (code) {
522         case 0: /* Implementation is still a stub, or the code wasn't set */
523                 is_valid = response->message == NULL;
524                 break;
525         case 500: /* Internal Server Error */
526         case 501: /* Not Implemented */
527         case 404: /* Channel not found */
528         case 409: /* Channel not in a Stasis application */
529                 is_valid = 1;
530                 break;
531         default:
532                 if (200 <= code && code <= 299) {
533                         is_valid = ast_ari_validate_void(
534                                 response->message);
535                 } else {
536                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/unmute\n", code);
537                         is_valid = 0;
538                 }
539         }
540
541         if (!is_valid) {
542                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/unmute\n");
543                 ast_ari_response_error(response, 500,
544                         "Internal Server Error", "Response validation failed");
545         }
546 #endif /* AST_DEVMODE */
547
548 fin: __attribute__((unused))
549         return;
550 }
551 /*!
552  * \brief Parameter parsing callback for /channels/{channelId}/hold.
553  * \param get_params GET parameters in the HTTP request.
554  * \param path_vars Path variables extracted from the request.
555  * \param headers HTTP headers.
556  * \param[out] response Response to the HTTP request.
557  */
558 static void ast_ari_hold_channel_cb(
559         struct ast_variable *get_params, struct ast_variable *path_vars,
560         struct ast_variable *headers, struct ast_ari_response *response)
561 {
562         struct ast_hold_channel_args args = {};
563         struct ast_variable *i;
564 #if defined(AST_DEVMODE)
565         int is_valid;
566         int code;
567 #endif /* AST_DEVMODE */
568
569         for (i = path_vars; i; i = i->next) {
570                 if (strcmp(i->name, "channelId") == 0) {
571                         args.channel_id = (i->value);
572                 } else
573                 {}
574         }
575         ast_ari_hold_channel(headers, &args, response);
576 #if defined(AST_DEVMODE)
577         code = response->response_code;
578
579         switch (code) {
580         case 0: /* Implementation is still a stub, or the code wasn't set */
581                 is_valid = response->message == NULL;
582                 break;
583         case 500: /* Internal Server Error */
584         case 501: /* Not Implemented */
585         case 404: /* Channel not found */
586         case 409: /* Channel not in a Stasis application */
587                 is_valid = 1;
588                 break;
589         default:
590                 if (200 <= code && code <= 299) {
591                         is_valid = ast_ari_validate_void(
592                                 response->message);
593                 } else {
594                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/hold\n", code);
595                         is_valid = 0;
596                 }
597         }
598
599         if (!is_valid) {
600                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/hold\n");
601                 ast_ari_response_error(response, 500,
602                         "Internal Server Error", "Response validation failed");
603         }
604 #endif /* AST_DEVMODE */
605
606 fin: __attribute__((unused))
607         return;
608 }
609 /*!
610  * \brief Parameter parsing callback for /channels/{channelId}/hold.
611  * \param get_params GET parameters in the HTTP request.
612  * \param path_vars Path variables extracted from the request.
613  * \param headers HTTP headers.
614  * \param[out] response Response to the HTTP request.
615  */
616 static void ast_ari_unhold_channel_cb(
617         struct ast_variable *get_params, struct ast_variable *path_vars,
618         struct ast_variable *headers, struct ast_ari_response *response)
619 {
620         struct ast_unhold_channel_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 = path_vars; i; i = i->next) {
628                 if (strcmp(i->name, "channelId") == 0) {
629                         args.channel_id = (i->value);
630                 } else
631                 {}
632         }
633         ast_ari_unhold_channel(headers, &args, response);
634 #if defined(AST_DEVMODE)
635         code = response->response_code;
636
637         switch (code) {
638         case 0: /* Implementation is still a stub, or the code wasn't set */
639                 is_valid = response->message == NULL;
640                 break;
641         case 500: /* Internal Server Error */
642         case 501: /* Not Implemented */
643         case 404: /* Channel not found */
644         case 409: /* Channel not in a Stasis application */
645                 is_valid = 1;
646                 break;
647         default:
648                 if (200 <= code && code <= 299) {
649                         is_valid = ast_ari_validate_void(
650                                 response->message);
651                 } else {
652                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/hold\n", code);
653                         is_valid = 0;
654                 }
655         }
656
657         if (!is_valid) {
658                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/hold\n");
659                 ast_ari_response_error(response, 500,
660                         "Internal Server Error", "Response validation failed");
661         }
662 #endif /* AST_DEVMODE */
663
664 fin: __attribute__((unused))
665         return;
666 }
667 /*!
668  * \brief Parameter parsing callback for /channels/{channelId}/moh.
669  * \param get_params GET parameters in the HTTP request.
670  * \param path_vars Path variables extracted from the request.
671  * \param headers HTTP headers.
672  * \param[out] response Response to the HTTP request.
673  */
674 static void ast_ari_moh_start_channel_cb(
675         struct ast_variable *get_params, struct ast_variable *path_vars,
676         struct ast_variable *headers, struct ast_ari_response *response)
677 {
678         struct ast_moh_start_channel_args args = {};
679         struct ast_variable *i;
680 #if defined(AST_DEVMODE)
681         int is_valid;
682         int code;
683 #endif /* AST_DEVMODE */
684
685         for (i = get_params; i; i = i->next) {
686                 if (strcmp(i->name, "mohClass") == 0) {
687                         args.moh_class = (i->value);
688                 } else
689                 {}
690         }
691         for (i = path_vars; i; i = i->next) {
692                 if (strcmp(i->name, "channelId") == 0) {
693                         args.channel_id = (i->value);
694                 } else
695                 {}
696         }
697         ast_ari_moh_start_channel(headers, &args, response);
698 #if defined(AST_DEVMODE)
699         code = response->response_code;
700
701         switch (code) {
702         case 0: /* Implementation is still a stub, or the code wasn't set */
703                 is_valid = response->message == NULL;
704                 break;
705         case 500: /* Internal Server Error */
706         case 501: /* Not Implemented */
707         case 404: /* Channel not found */
708         case 409: /* Channel not in a Stasis application */
709                 is_valid = 1;
710                 break;
711         default:
712                 if (200 <= code && code <= 299) {
713                         is_valid = ast_ari_validate_void(
714                                 response->message);
715                 } else {
716                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/moh\n", code);
717                         is_valid = 0;
718                 }
719         }
720
721         if (!is_valid) {
722                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/moh\n");
723                 ast_ari_response_error(response, 500,
724                         "Internal Server Error", "Response validation failed");
725         }
726 #endif /* AST_DEVMODE */
727
728 fin: __attribute__((unused))
729         return;
730 }
731 /*!
732  * \brief Parameter parsing callback for /channels/{channelId}/moh.
733  * \param get_params GET parameters in the HTTP request.
734  * \param path_vars Path variables extracted from the request.
735  * \param headers HTTP headers.
736  * \param[out] response Response to the HTTP request.
737  */
738 static void ast_ari_moh_stop_channel_cb(
739         struct ast_variable *get_params, struct ast_variable *path_vars,
740         struct ast_variable *headers, struct ast_ari_response *response)
741 {
742         struct ast_moh_stop_channel_args args = {};
743         struct ast_variable *i;
744 #if defined(AST_DEVMODE)
745         int is_valid;
746         int code;
747 #endif /* AST_DEVMODE */
748
749         for (i = path_vars; i; i = i->next) {
750                 if (strcmp(i->name, "channelId") == 0) {
751                         args.channel_id = (i->value);
752                 } else
753                 {}
754         }
755         ast_ari_moh_stop_channel(headers, &args, response);
756 #if defined(AST_DEVMODE)
757         code = response->response_code;
758
759         switch (code) {
760         case 0: /* Implementation is still a stub, or the code wasn't set */
761                 is_valid = response->message == NULL;
762                 break;
763         case 500: /* Internal Server Error */
764         case 501: /* Not Implemented */
765         case 404: /* Channel not found */
766         case 409: /* Channel not in a Stasis application */
767                 is_valid = 1;
768                 break;
769         default:
770                 if (200 <= code && code <= 299) {
771                         is_valid = ast_ari_validate_void(
772                                 response->message);
773                 } else {
774                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/moh\n", code);
775                         is_valid = 0;
776                 }
777         }
778
779         if (!is_valid) {
780                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/moh\n");
781                 ast_ari_response_error(response, 500,
782                         "Internal Server Error", "Response validation failed");
783         }
784 #endif /* AST_DEVMODE */
785
786 fin: __attribute__((unused))
787         return;
788 }
789 /*!
790  * \brief Parameter parsing callback for /channels/{channelId}/play.
791  * \param get_params GET parameters in the HTTP request.
792  * \param path_vars Path variables extracted from the request.
793  * \param headers HTTP headers.
794  * \param[out] response Response to the HTTP request.
795  */
796 static void ast_ari_play_on_channel_cb(
797         struct ast_variable *get_params, struct ast_variable *path_vars,
798         struct ast_variable *headers, struct ast_ari_response *response)
799 {
800         struct ast_play_on_channel_args args = {};
801         struct ast_variable *i;
802 #if defined(AST_DEVMODE)
803         int is_valid;
804         int code;
805 #endif /* AST_DEVMODE */
806
807         for (i = get_params; i; i = i->next) {
808                 if (strcmp(i->name, "media") == 0) {
809                         args.media = (i->value);
810                 } else
811                 if (strcmp(i->name, "lang") == 0) {
812                         args.lang = (i->value);
813                 } else
814                 if (strcmp(i->name, "offsetms") == 0) {
815                         args.offsetms = atoi(i->value);
816                 } else
817                 if (strcmp(i->name, "skipms") == 0) {
818                         args.skipms = atoi(i->value);
819                 } else
820                 {}
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_play_on_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_playback(
845                                 response->message);
846                 } else {
847                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/play\n", code);
848                         is_valid = 0;
849                 }
850         }
851
852         if (!is_valid) {
853                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/play\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}/record.
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_record_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_record_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, "name") == 0) {
882                         args.name = (i->value);
883                 } else
884                 if (strcmp(i->name, "format") == 0) {
885                         args.format = (i->value);
886                 } else
887                 if (strcmp(i->name, "maxDurationSeconds") == 0) {
888                         args.max_duration_seconds = atoi(i->value);
889                 } else
890                 if (strcmp(i->name, "maxSilenceSeconds") == 0) {
891                         args.max_silence_seconds = atoi(i->value);
892                 } else
893                 if (strcmp(i->name, "ifExists") == 0) {
894                         args.if_exists = (i->value);
895                 } else
896                 if (strcmp(i->name, "beep") == 0) {
897                         args.beep = ast_true(i->value);
898                 } else
899                 if (strcmp(i->name, "terminateOn") == 0) {
900                         args.terminate_on = (i->value);
901                 } else
902                 {}
903         }
904         for (i = path_vars; i; i = i->next) {
905                 if (strcmp(i->name, "channelId") == 0) {
906                         args.channel_id = (i->value);
907                 } else
908                 {}
909         }
910         ast_ari_record_channel(headers, &args, response);
911 #if defined(AST_DEVMODE)
912         code = response->response_code;
913
914         switch (code) {
915         case 0: /* Implementation is still a stub, or the code wasn't set */
916                 is_valid = response->message == NULL;
917                 break;
918         case 500: /* Internal Server Error */
919         case 501: /* Not Implemented */
920         case 400: /* Invalid parameters */
921         case 404: /* Channel not found */
922         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 */
923         case 422: /* The format specified is unknown on this system */
924                 is_valid = 1;
925                 break;
926         default:
927                 if (200 <= code && code <= 299) {
928                         is_valid = ast_ari_validate_live_recording(
929                                 response->message);
930                 } else {
931                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/record\n", code);
932                         is_valid = 0;
933                 }
934         }
935
936         if (!is_valid) {
937                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/record\n");
938                 ast_ari_response_error(response, 500,
939                         "Internal Server Error", "Response validation failed");
940         }
941 #endif /* AST_DEVMODE */
942
943 fin: __attribute__((unused))
944         return;
945 }
946 /*!
947  * \brief Parameter parsing callback for /channels/{channelId}/variable.
948  * \param get_params GET parameters in the HTTP request.
949  * \param path_vars Path variables extracted from the request.
950  * \param headers HTTP headers.
951  * \param[out] response Response to the HTTP request.
952  */
953 static void ast_ari_get_channel_var_cb(
954         struct ast_variable *get_params, struct ast_variable *path_vars,
955         struct ast_variable *headers, struct ast_ari_response *response)
956 {
957         struct ast_get_channel_var_args args = {};
958         struct ast_variable *i;
959 #if defined(AST_DEVMODE)
960         int is_valid;
961         int code;
962 #endif /* AST_DEVMODE */
963
964         for (i = get_params; i; i = i->next) {
965                 if (strcmp(i->name, "variable") == 0) {
966                         args.variable = (i->value);
967                 } else
968                 {}
969         }
970         for (i = path_vars; i; i = i->next) {
971                 if (strcmp(i->name, "channelId") == 0) {
972                         args.channel_id = (i->value);
973                 } else
974                 {}
975         }
976         ast_ari_get_channel_var(headers, &args, response);
977 #if defined(AST_DEVMODE)
978         code = response->response_code;
979
980         switch (code) {
981         case 0: /* Implementation is still a stub, or the code wasn't set */
982                 is_valid = response->message == NULL;
983                 break;
984         case 500: /* Internal Server Error */
985         case 501: /* Not Implemented */
986         case 400: /* Missing variable parameter. */
987         case 404: /* Channel not found */
988         case 409: /* Channel not in a Stasis application */
989                 is_valid = 1;
990                 break;
991         default:
992                 if (200 <= code && code <= 299) {
993                         is_valid = ast_ari_validate_variable(
994                                 response->message);
995                 } else {
996                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/variable\n", code);
997                         is_valid = 0;
998                 }
999         }
1000
1001         if (!is_valid) {
1002                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/variable\n");
1003                 ast_ari_response_error(response, 500,
1004                         "Internal Server Error", "Response validation failed");
1005         }
1006 #endif /* AST_DEVMODE */
1007
1008 fin: __attribute__((unused))
1009         return;
1010 }
1011 /*!
1012  * \brief Parameter parsing callback for /channels/{channelId}/variable.
1013  * \param get_params GET parameters in the HTTP request.
1014  * \param path_vars Path variables extracted from the request.
1015  * \param headers HTTP headers.
1016  * \param[out] response Response to the HTTP request.
1017  */
1018 static void ast_ari_set_channel_var_cb(
1019         struct ast_variable *get_params, struct ast_variable *path_vars,
1020         struct ast_variable *headers, struct ast_ari_response *response)
1021 {
1022         struct ast_set_channel_var_args args = {};
1023         struct ast_variable *i;
1024 #if defined(AST_DEVMODE)
1025         int is_valid;
1026         int code;
1027 #endif /* AST_DEVMODE */
1028
1029         for (i = get_params; i; i = i->next) {
1030                 if (strcmp(i->name, "variable") == 0) {
1031                         args.variable = (i->value);
1032                 } else
1033                 if (strcmp(i->name, "value") == 0) {
1034                         args.value = (i->value);
1035                 } else
1036                 {}
1037         }
1038         for (i = path_vars; i; i = i->next) {
1039                 if (strcmp(i->name, "channelId") == 0) {
1040                         args.channel_id = (i->value);
1041                 } else
1042                 {}
1043         }
1044         ast_ari_set_channel_var(headers, &args, response);
1045 #if defined(AST_DEVMODE)
1046         code = response->response_code;
1047
1048         switch (code) {
1049         case 0: /* Implementation is still a stub, or the code wasn't set */
1050                 is_valid = response->message == NULL;
1051                 break;
1052         case 500: /* Internal Server Error */
1053         case 501: /* Not Implemented */
1054         case 400: /* Missing variable parameter. */
1055         case 404: /* Channel not found */
1056         case 409: /* Channel not in a Stasis application */
1057                 is_valid = 1;
1058                 break;
1059         default:
1060                 if (200 <= code && code <= 299) {
1061                         is_valid = ast_ari_validate_void(
1062                                 response->message);
1063                 } else {
1064                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/variable\n", code);
1065                         is_valid = 0;
1066                 }
1067         }
1068
1069         if (!is_valid) {
1070                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/variable\n");
1071                 ast_ari_response_error(response, 500,
1072                         "Internal Server Error", "Response validation failed");
1073         }
1074 #endif /* AST_DEVMODE */
1075
1076 fin: __attribute__((unused))
1077         return;
1078 }
1079
1080 /*! \brief REST handler for /api-docs/channels.{format} */
1081 static struct stasis_rest_handlers channels_channelId_continue = {
1082         .path_segment = "continue",
1083         .callbacks = {
1084                 [AST_HTTP_POST] = ast_ari_continue_in_dialplan_cb,
1085         },
1086         .num_children = 0,
1087         .children = {  }
1088 };
1089 /*! \brief REST handler for /api-docs/channels.{format} */
1090 static struct stasis_rest_handlers channels_channelId_answer = {
1091         .path_segment = "answer",
1092         .callbacks = {
1093                 [AST_HTTP_POST] = ast_ari_answer_channel_cb,
1094         },
1095         .num_children = 0,
1096         .children = {  }
1097 };
1098 /*! \brief REST handler for /api-docs/channels.{format} */
1099 static struct stasis_rest_handlers channels_channelId_mute = {
1100         .path_segment = "mute",
1101         .callbacks = {
1102                 [AST_HTTP_POST] = ast_ari_mute_channel_cb,
1103         },
1104         .num_children = 0,
1105         .children = {  }
1106 };
1107 /*! \brief REST handler for /api-docs/channels.{format} */
1108 static struct stasis_rest_handlers channels_channelId_unmute = {
1109         .path_segment = "unmute",
1110         .callbacks = {
1111                 [AST_HTTP_POST] = ast_ari_unmute_channel_cb,
1112         },
1113         .num_children = 0,
1114         .children = {  }
1115 };
1116 /*! \brief REST handler for /api-docs/channels.{format} */
1117 static struct stasis_rest_handlers channels_channelId_hold = {
1118         .path_segment = "hold",
1119         .callbacks = {
1120                 [AST_HTTP_POST] = ast_ari_hold_channel_cb,
1121                 [AST_HTTP_DELETE] = ast_ari_unhold_channel_cb,
1122         },
1123         .num_children = 0,
1124         .children = {  }
1125 };
1126 /*! \brief REST handler for /api-docs/channels.{format} */
1127 static struct stasis_rest_handlers channels_channelId_moh = {
1128         .path_segment = "moh",
1129         .callbacks = {
1130                 [AST_HTTP_POST] = ast_ari_moh_start_channel_cb,
1131                 [AST_HTTP_DELETE] = ast_ari_moh_stop_channel_cb,
1132         },
1133         .num_children = 0,
1134         .children = {  }
1135 };
1136 /*! \brief REST handler for /api-docs/channels.{format} */
1137 static struct stasis_rest_handlers channels_channelId_play = {
1138         .path_segment = "play",
1139         .callbacks = {
1140                 [AST_HTTP_POST] = ast_ari_play_on_channel_cb,
1141         },
1142         .num_children = 0,
1143         .children = {  }
1144 };
1145 /*! \brief REST handler for /api-docs/channels.{format} */
1146 static struct stasis_rest_handlers channels_channelId_record = {
1147         .path_segment = "record",
1148         .callbacks = {
1149                 [AST_HTTP_POST] = ast_ari_record_channel_cb,
1150         },
1151         .num_children = 0,
1152         .children = {  }
1153 };
1154 /*! \brief REST handler for /api-docs/channels.{format} */
1155 static struct stasis_rest_handlers channels_channelId_variable = {
1156         .path_segment = "variable",
1157         .callbacks = {
1158                 [AST_HTTP_GET] = ast_ari_get_channel_var_cb,
1159                 [AST_HTTP_POST] = ast_ari_set_channel_var_cb,
1160         },
1161         .num_children = 0,
1162         .children = {  }
1163 };
1164 /*! \brief REST handler for /api-docs/channels.{format} */
1165 static struct stasis_rest_handlers channels_channelId = {
1166         .path_segment = "channelId",
1167         .is_wildcard = 1,
1168         .callbacks = {
1169                 [AST_HTTP_GET] = ast_ari_get_channel_cb,
1170                 [AST_HTTP_DELETE] = ast_ari_delete_channel_cb,
1171         },
1172         .num_children = 9,
1173         .children = { &channels_channelId_continue,&channels_channelId_answer,&channels_channelId_mute,&channels_channelId_unmute,&channels_channelId_hold,&channels_channelId_moh,&channels_channelId_play,&channels_channelId_record,&channels_channelId_variable, }
1174 };
1175 /*! \brief REST handler for /api-docs/channels.{format} */
1176 static struct stasis_rest_handlers channels = {
1177         .path_segment = "channels",
1178         .callbacks = {
1179                 [AST_HTTP_GET] = ast_ari_get_channels_cb,
1180                 [AST_HTTP_POST] = ast_ari_originate_cb,
1181         },
1182         .num_children = 1,
1183         .children = { &channels_channelId, }
1184 };
1185
1186 static int load_module(void)
1187 {
1188         int res = 0;
1189         stasis_app_ref();
1190         res |= ast_ari_add_handler(&channels);
1191         return res;
1192 }
1193
1194 static int unload_module(void)
1195 {
1196         ast_ari_remove_handler(&channels);
1197         stasis_app_unref();
1198         return 0;
1199 }
1200
1201 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "RESTful API module - Channel resources",
1202         .load = load_module,
1203         .unload = unload_module,
1204         .nonoptreq = "res_ari,res_stasis",
1205         );