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