82cb1740f7ad2724b9b89ea031fdf3825f4ca38d
[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_channels_list_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_ari_channels_list_args args = {};
66 #if defined(AST_DEVMODE)
67         int is_valid;
68         int code;
69 #endif /* AST_DEVMODE */
70
71         ast_ari_channels_list(headers, &args, response);
72 #if defined(AST_DEVMODE)
73         code = response->response_code;
74
75         switch (code) {
76         case 0: /* Implementation is still a stub, or the code wasn't set */
77                 is_valid = response->message == NULL;
78                 break;
79         case 500: /* Internal Server Error */
80         case 501: /* Not Implemented */
81                 is_valid = 1;
82                 break;
83         default:
84                 if (200 <= code && code <= 299) {
85                         is_valid = ast_ari_validate_list(response->message,
86                                 ast_ari_validate_channel_fn());
87                 } else {
88                         ast_log(LOG_ERROR, "Invalid error response %d for /channels\n", code);
89                         is_valid = 0;
90                 }
91         }
92
93         if (!is_valid) {
94                 ast_log(LOG_ERROR, "Response validation failed for /channels\n");
95                 ast_ari_response_error(response, 500,
96                         "Internal Server Error", "Response validation failed");
97         }
98 #endif /* AST_DEVMODE */
99
100 fin: __attribute__((unused))
101         return;
102 }
103 /*!
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_channels_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_ari_channels_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_channels_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_channels_get_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_ari_channels_get_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_channels_get(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_channels_hangup_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_ari_channels_hangup_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 = get_params; i; i = i->next) {
257                 if (strcmp(i->name, "reason") == 0) {
258                         args.reason = (i->value);
259                 } else
260                 {}
261         }
262         for (i = path_vars; i; i = i->next) {
263                 if (strcmp(i->name, "channelId") == 0) {
264                         args.channel_id = (i->value);
265                 } else
266                 {}
267         }
268         ast_ari_channels_hangup(headers, &args, response);
269 #if defined(AST_DEVMODE)
270         code = response->response_code;
271
272         switch (code) {
273         case 0: /* Implementation is still a stub, or the code wasn't set */
274                 is_valid = response->message == NULL;
275                 break;
276         case 500: /* Internal Server Error */
277         case 501: /* Not Implemented */
278         case 400: /* Invalid reason for hangup provided */
279         case 404: /* Channel not found */
280                 is_valid = 1;
281                 break;
282         default:
283                 if (200 <= code && code <= 299) {
284                         is_valid = ast_ari_validate_void(
285                                 response->message);
286                 } else {
287                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}\n", code);
288                         is_valid = 0;
289                 }
290         }
291
292         if (!is_valid) {
293                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}\n");
294                 ast_ari_response_error(response, 500,
295                         "Internal Server Error", "Response validation failed");
296         }
297 #endif /* AST_DEVMODE */
298
299 fin: __attribute__((unused))
300         return;
301 }
302 /*!
303  * \brief Parameter parsing callback for /channels/{channelId}/continue.
304  * \param get_params GET parameters in the HTTP request.
305  * \param path_vars Path variables extracted from the request.
306  * \param headers HTTP headers.
307  * \param[out] response Response to the HTTP request.
308  */
309 static void ast_ari_channels_continue_in_dialplan_cb(
310         struct ast_variable *get_params, struct ast_variable *path_vars,
311         struct ast_variable *headers, struct ast_ari_response *response)
312 {
313         struct ast_ari_channels_continue_in_dialplan_args args = {};
314         struct ast_variable *i;
315 #if defined(AST_DEVMODE)
316         int is_valid;
317         int code;
318 #endif /* AST_DEVMODE */
319
320         for (i = get_params; i; i = i->next) {
321                 if (strcmp(i->name, "context") == 0) {
322                         args.context = (i->value);
323                 } else
324                 if (strcmp(i->name, "extension") == 0) {
325                         args.extension = (i->value);
326                 } else
327                 if (strcmp(i->name, "priority") == 0) {
328                         args.priority = atoi(i->value);
329                 } else
330                 {}
331         }
332         for (i = path_vars; i; i = i->next) {
333                 if (strcmp(i->name, "channelId") == 0) {
334                         args.channel_id = (i->value);
335                 } else
336                 {}
337         }
338         ast_ari_channels_continue_in_dialplan(headers, &args, response);
339 #if defined(AST_DEVMODE)
340         code = response->response_code;
341
342         switch (code) {
343         case 0: /* Implementation is still a stub, or the code wasn't set */
344                 is_valid = response->message == NULL;
345                 break;
346         case 500: /* Internal Server Error */
347         case 501: /* Not Implemented */
348         case 404: /* Channel not found */
349         case 409: /* Channel not in a Stasis application */
350                 is_valid = 1;
351                 break;
352         default:
353                 if (200 <= code && code <= 299) {
354                         is_valid = ast_ari_validate_void(
355                                 response->message);
356                 } else {
357                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/continue\n", code);
358                         is_valid = 0;
359                 }
360         }
361
362         if (!is_valid) {
363                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/continue\n");
364                 ast_ari_response_error(response, 500,
365                         "Internal Server Error", "Response validation failed");
366         }
367 #endif /* AST_DEVMODE */
368
369 fin: __attribute__((unused))
370         return;
371 }
372 /*!
373  * \brief Parameter parsing callback for /channels/{channelId}/answer.
374  * \param get_params GET parameters in the HTTP request.
375  * \param path_vars Path variables extracted from the request.
376  * \param headers HTTP headers.
377  * \param[out] response Response to the HTTP request.
378  */
379 static void ast_ari_channels_answer_cb(
380         struct ast_variable *get_params, struct ast_variable *path_vars,
381         struct ast_variable *headers, struct ast_ari_response *response)
382 {
383         struct ast_ari_channels_answer_args args = {};
384         struct ast_variable *i;
385 #if defined(AST_DEVMODE)
386         int is_valid;
387         int code;
388 #endif /* AST_DEVMODE */
389
390         for (i = path_vars; i; i = i->next) {
391                 if (strcmp(i->name, "channelId") == 0) {
392                         args.channel_id = (i->value);
393                 } else
394                 {}
395         }
396         ast_ari_channels_answer(headers, &args, response);
397 #if defined(AST_DEVMODE)
398         code = response->response_code;
399
400         switch (code) {
401         case 0: /* Implementation is still a stub, or the code wasn't set */
402                 is_valid = response->message == NULL;
403                 break;
404         case 500: /* Internal Server Error */
405         case 501: /* Not Implemented */
406         case 404: /* Channel not found */
407         case 409: /* Channel not in a Stasis application */
408                 is_valid = 1;
409                 break;
410         default:
411                 if (200 <= code && code <= 299) {
412                         is_valid = ast_ari_validate_void(
413                                 response->message);
414                 } else {
415                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/answer\n", code);
416                         is_valid = 0;
417                 }
418         }
419
420         if (!is_valid) {
421                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/answer\n");
422                 ast_ari_response_error(response, 500,
423                         "Internal Server Error", "Response validation failed");
424         }
425 #endif /* AST_DEVMODE */
426
427 fin: __attribute__((unused))
428         return;
429 }
430 /*!
431  * \brief Parameter parsing callback for /channels/{channelId}/ring.
432  * \param get_params GET parameters in the HTTP request.
433  * \param path_vars Path variables extracted from the request.
434  * \param headers HTTP headers.
435  * \param[out] response Response to the HTTP request.
436  */
437 static void ast_ari_channels_ring_cb(
438         struct ast_variable *get_params, struct ast_variable *path_vars,
439         struct ast_variable *headers, struct ast_ari_response *response)
440 {
441         struct ast_ari_channels_ring_args args = {};
442         struct ast_variable *i;
443 #if defined(AST_DEVMODE)
444         int is_valid;
445         int code;
446 #endif /* AST_DEVMODE */
447
448         for (i = path_vars; i; i = i->next) {
449                 if (strcmp(i->name, "channelId") == 0) {
450                         args.channel_id = (i->value);
451                 } else
452                 {}
453         }
454         ast_ari_channels_ring(headers, &args, response);
455 #if defined(AST_DEVMODE)
456         code = response->response_code;
457
458         switch (code) {
459         case 0: /* Implementation is still a stub, or the code wasn't set */
460                 is_valid = response->message == NULL;
461                 break;
462         case 500: /* Internal Server Error */
463         case 501: /* Not Implemented */
464         case 404: /* Channel not found */
465         case 409: /* Channel not in a Stasis application */
466                 is_valid = 1;
467                 break;
468         default:
469                 if (200 <= code && code <= 299) {
470                         is_valid = ast_ari_validate_void(
471                                 response->message);
472                 } else {
473                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/ring\n", code);
474                         is_valid = 0;
475                 }
476         }
477
478         if (!is_valid) {
479                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/ring\n");
480                 ast_ari_response_error(response, 500,
481                         "Internal Server Error", "Response validation failed");
482         }
483 #endif /* AST_DEVMODE */
484
485 fin: __attribute__((unused))
486         return;
487 }
488 /*!
489  * \brief Parameter parsing callback for /channels/{channelId}/dtmf.
490  * \param get_params GET parameters in the HTTP request.
491  * \param path_vars Path variables extracted from the request.
492  * \param headers HTTP headers.
493  * \param[out] response Response to the HTTP request.
494  */
495 static void ast_ari_channels_send_dtmf_cb(
496         struct ast_variable *get_params, struct ast_variable *path_vars,
497         struct ast_variable *headers, struct ast_ari_response *response)
498 {
499         struct ast_ari_channels_send_dtmf_args args = {};
500         struct ast_variable *i;
501 #if defined(AST_DEVMODE)
502         int is_valid;
503         int code;
504 #endif /* AST_DEVMODE */
505
506         for (i = get_params; i; i = i->next) {
507                 if (strcmp(i->name, "dtmf") == 0) {
508                         args.dtmf = (i->value);
509                 } else
510                 if (strcmp(i->name, "before") == 0) {
511                         args.before = atoi(i->value);
512                 } else
513                 if (strcmp(i->name, "between") == 0) {
514                         args.between = atoi(i->value);
515                 } else
516                 if (strcmp(i->name, "duration") == 0) {
517                         args.duration = atoi(i->value);
518                 } else
519                 if (strcmp(i->name, "after") == 0) {
520                         args.after = atoi(i->value);
521                 } else
522                 {}
523         }
524         for (i = path_vars; i; i = i->next) {
525                 if (strcmp(i->name, "channelId") == 0) {
526                         args.channel_id = (i->value);
527                 } else
528                 {}
529         }
530         ast_ari_channels_send_dtmf(headers, &args, response);
531 #if defined(AST_DEVMODE)
532         code = response->response_code;
533
534         switch (code) {
535         case 0: /* Implementation is still a stub, or the code wasn't set */
536                 is_valid = response->message == NULL;
537                 break;
538         case 500: /* Internal Server Error */
539         case 501: /* Not Implemented */
540         case 400: /* DTMF is required */
541         case 404: /* Channel not found */
542         case 409: /* Channel not in a Stasis application */
543                 is_valid = 1;
544                 break;
545         default:
546                 if (200 <= code && code <= 299) {
547                         is_valid = ast_ari_validate_void(
548                                 response->message);
549                 } else {
550                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/dtmf\n", code);
551                         is_valid = 0;
552                 }
553         }
554
555         if (!is_valid) {
556                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/dtmf\n");
557                 ast_ari_response_error(response, 500,
558                         "Internal Server Error", "Response validation failed");
559         }
560 #endif /* AST_DEVMODE */
561
562 fin: __attribute__((unused))
563         return;
564 }
565 /*!
566  * \brief Parameter parsing callback for /channels/{channelId}/mute.
567  * \param get_params GET parameters in the HTTP request.
568  * \param path_vars Path variables extracted from the request.
569  * \param headers HTTP headers.
570  * \param[out] response Response to the HTTP request.
571  */
572 static void ast_ari_channels_mute_cb(
573         struct ast_variable *get_params, struct ast_variable *path_vars,
574         struct ast_variable *headers, struct ast_ari_response *response)
575 {
576         struct ast_ari_channels_mute_args args = {};
577         struct ast_variable *i;
578 #if defined(AST_DEVMODE)
579         int is_valid;
580         int code;
581 #endif /* AST_DEVMODE */
582
583         for (i = get_params; i; i = i->next) {
584                 if (strcmp(i->name, "direction") == 0) {
585                         args.direction = (i->value);
586                 } else
587                 {}
588         }
589         for (i = path_vars; i; i = i->next) {
590                 if (strcmp(i->name, "channelId") == 0) {
591                         args.channel_id = (i->value);
592                 } else
593                 {}
594         }
595         ast_ari_channels_mute(headers, &args, response);
596 #if defined(AST_DEVMODE)
597         code = response->response_code;
598
599         switch (code) {
600         case 0: /* Implementation is still a stub, or the code wasn't set */
601                 is_valid = response->message == NULL;
602                 break;
603         case 500: /* Internal Server Error */
604         case 501: /* Not Implemented */
605         case 404: /* Channel not found */
606         case 409: /* Channel not in a Stasis application */
607                 is_valid = 1;
608                 break;
609         default:
610                 if (200 <= code && code <= 299) {
611                         is_valid = ast_ari_validate_void(
612                                 response->message);
613                 } else {
614                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/mute\n", code);
615                         is_valid = 0;
616                 }
617         }
618
619         if (!is_valid) {
620                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/mute\n");
621                 ast_ari_response_error(response, 500,
622                         "Internal Server Error", "Response validation failed");
623         }
624 #endif /* AST_DEVMODE */
625
626 fin: __attribute__((unused))
627         return;
628 }
629 /*!
630  * \brief Parameter parsing callback for /channels/{channelId}/mute.
631  * \param get_params GET parameters in the HTTP request.
632  * \param path_vars Path variables extracted from the request.
633  * \param headers HTTP headers.
634  * \param[out] response Response to the HTTP request.
635  */
636 static void ast_ari_channels_unmute_cb(
637         struct ast_variable *get_params, struct ast_variable *path_vars,
638         struct ast_variable *headers, struct ast_ari_response *response)
639 {
640         struct ast_ari_channels_unmute_args args = {};
641         struct ast_variable *i;
642 #if defined(AST_DEVMODE)
643         int is_valid;
644         int code;
645 #endif /* AST_DEVMODE */
646
647         for (i = get_params; i; i = i->next) {
648                 if (strcmp(i->name, "direction") == 0) {
649                         args.direction = (i->value);
650                 } else
651                 {}
652         }
653         for (i = path_vars; i; i = i->next) {
654                 if (strcmp(i->name, "channelId") == 0) {
655                         args.channel_id = (i->value);
656                 } else
657                 {}
658         }
659         ast_ari_channels_unmute(headers, &args, response);
660 #if defined(AST_DEVMODE)
661         code = response->response_code;
662
663         switch (code) {
664         case 0: /* Implementation is still a stub, or the code wasn't set */
665                 is_valid = response->message == NULL;
666                 break;
667         case 500: /* Internal Server Error */
668         case 501: /* Not Implemented */
669         case 404: /* Channel not found */
670         case 409: /* Channel not in a Stasis application */
671                 is_valid = 1;
672                 break;
673         default:
674                 if (200 <= code && code <= 299) {
675                         is_valid = ast_ari_validate_void(
676                                 response->message);
677                 } else {
678                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/mute\n", code);
679                         is_valid = 0;
680                 }
681         }
682
683         if (!is_valid) {
684                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/mute\n");
685                 ast_ari_response_error(response, 500,
686                         "Internal Server Error", "Response validation failed");
687         }
688 #endif /* AST_DEVMODE */
689
690 fin: __attribute__((unused))
691         return;
692 }
693 /*!
694  * \brief Parameter parsing callback for /channels/{channelId}/hold.
695  * \param get_params GET parameters in the HTTP request.
696  * \param path_vars Path variables extracted from the request.
697  * \param headers HTTP headers.
698  * \param[out] response Response to the HTTP request.
699  */
700 static void ast_ari_channels_hold_cb(
701         struct ast_variable *get_params, struct ast_variable *path_vars,
702         struct ast_variable *headers, struct ast_ari_response *response)
703 {
704         struct ast_ari_channels_hold_args args = {};
705         struct ast_variable *i;
706 #if defined(AST_DEVMODE)
707         int is_valid;
708         int code;
709 #endif /* AST_DEVMODE */
710
711         for (i = path_vars; i; i = i->next) {
712                 if (strcmp(i->name, "channelId") == 0) {
713                         args.channel_id = (i->value);
714                 } else
715                 {}
716         }
717         ast_ari_channels_hold(headers, &args, response);
718 #if defined(AST_DEVMODE)
719         code = response->response_code;
720
721         switch (code) {
722         case 0: /* Implementation is still a stub, or the code wasn't set */
723                 is_valid = response->message == NULL;
724                 break;
725         case 500: /* Internal Server Error */
726         case 501: /* Not Implemented */
727         case 404: /* Channel not found */
728         case 409: /* Channel not in a Stasis application */
729                 is_valid = 1;
730                 break;
731         default:
732                 if (200 <= code && code <= 299) {
733                         is_valid = ast_ari_validate_void(
734                                 response->message);
735                 } else {
736                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/hold\n", code);
737                         is_valid = 0;
738                 }
739         }
740
741         if (!is_valid) {
742                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/hold\n");
743                 ast_ari_response_error(response, 500,
744                         "Internal Server Error", "Response validation failed");
745         }
746 #endif /* AST_DEVMODE */
747
748 fin: __attribute__((unused))
749         return;
750 }
751 /*!
752  * \brief Parameter parsing callback for /channels/{channelId}/hold.
753  * \param get_params GET parameters in the HTTP request.
754  * \param path_vars Path variables extracted from the request.
755  * \param headers HTTP headers.
756  * \param[out] response Response to the HTTP request.
757  */
758 static void ast_ari_channels_unhold_cb(
759         struct ast_variable *get_params, struct ast_variable *path_vars,
760         struct ast_variable *headers, struct ast_ari_response *response)
761 {
762         struct ast_ari_channels_unhold_args args = {};
763         struct ast_variable *i;
764 #if defined(AST_DEVMODE)
765         int is_valid;
766         int code;
767 #endif /* AST_DEVMODE */
768
769         for (i = path_vars; i; i = i->next) {
770                 if (strcmp(i->name, "channelId") == 0) {
771                         args.channel_id = (i->value);
772                 } else
773                 {}
774         }
775         ast_ari_channels_unhold(headers, &args, response);
776 #if defined(AST_DEVMODE)
777         code = response->response_code;
778
779         switch (code) {
780         case 0: /* Implementation is still a stub, or the code wasn't set */
781                 is_valid = response->message == NULL;
782                 break;
783         case 500: /* Internal Server Error */
784         case 501: /* Not Implemented */
785         case 404: /* Channel not found */
786         case 409: /* Channel not in a Stasis application */
787                 is_valid = 1;
788                 break;
789         default:
790                 if (200 <= code && code <= 299) {
791                         is_valid = ast_ari_validate_void(
792                                 response->message);
793                 } else {
794                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/hold\n", code);
795                         is_valid = 0;
796                 }
797         }
798
799         if (!is_valid) {
800                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/hold\n");
801                 ast_ari_response_error(response, 500,
802                         "Internal Server Error", "Response validation failed");
803         }
804 #endif /* AST_DEVMODE */
805
806 fin: __attribute__((unused))
807         return;
808 }
809 /*!
810  * \brief Parameter parsing callback for /channels/{channelId}/moh.
811  * \param get_params GET parameters in the HTTP request.
812  * \param path_vars Path variables extracted from the request.
813  * \param headers HTTP headers.
814  * \param[out] response Response to the HTTP request.
815  */
816 static void ast_ari_channels_start_moh_cb(
817         struct ast_variable *get_params, struct ast_variable *path_vars,
818         struct ast_variable *headers, struct ast_ari_response *response)
819 {
820         struct ast_ari_channels_start_moh_args args = {};
821         struct ast_variable *i;
822 #if defined(AST_DEVMODE)
823         int is_valid;
824         int code;
825 #endif /* AST_DEVMODE */
826
827         for (i = get_params; i; i = i->next) {
828                 if (strcmp(i->name, "mohClass") == 0) {
829                         args.moh_class = (i->value);
830                 } else
831                 {}
832         }
833         for (i = path_vars; i; i = i->next) {
834                 if (strcmp(i->name, "channelId") == 0) {
835                         args.channel_id = (i->value);
836                 } else
837                 {}
838         }
839         ast_ari_channels_start_moh(headers, &args, response);
840 #if defined(AST_DEVMODE)
841         code = response->response_code;
842
843         switch (code) {
844         case 0: /* Implementation is still a stub, or the code wasn't set */
845                 is_valid = response->message == NULL;
846                 break;
847         case 500: /* Internal Server Error */
848         case 501: /* Not Implemented */
849         case 404: /* Channel not found */
850         case 409: /* Channel not in a Stasis application */
851                 is_valid = 1;
852                 break;
853         default:
854                 if (200 <= code && code <= 299) {
855                         is_valid = ast_ari_validate_void(
856                                 response->message);
857                 } else {
858                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/moh\n", code);
859                         is_valid = 0;
860                 }
861         }
862
863         if (!is_valid) {
864                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/moh\n");
865                 ast_ari_response_error(response, 500,
866                         "Internal Server Error", "Response validation failed");
867         }
868 #endif /* AST_DEVMODE */
869
870 fin: __attribute__((unused))
871         return;
872 }
873 /*!
874  * \brief Parameter parsing callback for /channels/{channelId}/moh.
875  * \param get_params GET parameters in the HTTP request.
876  * \param path_vars Path variables extracted from the request.
877  * \param headers HTTP headers.
878  * \param[out] response Response to the HTTP request.
879  */
880 static void ast_ari_channels_stop_moh_cb(
881         struct ast_variable *get_params, struct ast_variable *path_vars,
882         struct ast_variable *headers, struct ast_ari_response *response)
883 {
884         struct ast_ari_channels_stop_moh_args args = {};
885         struct ast_variable *i;
886 #if defined(AST_DEVMODE)
887         int is_valid;
888         int code;
889 #endif /* AST_DEVMODE */
890
891         for (i = path_vars; i; i = i->next) {
892                 if (strcmp(i->name, "channelId") == 0) {
893                         args.channel_id = (i->value);
894                 } else
895                 {}
896         }
897         ast_ari_channels_stop_moh(headers, &args, response);
898 #if defined(AST_DEVMODE)
899         code = response->response_code;
900
901         switch (code) {
902         case 0: /* Implementation is still a stub, or the code wasn't set */
903                 is_valid = response->message == NULL;
904                 break;
905         case 500: /* Internal Server Error */
906         case 501: /* Not Implemented */
907         case 404: /* Channel not found */
908         case 409: /* Channel not in a Stasis application */
909                 is_valid = 1;
910                 break;
911         default:
912                 if (200 <= code && code <= 299) {
913                         is_valid = ast_ari_validate_void(
914                                 response->message);
915                 } else {
916                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/moh\n", code);
917                         is_valid = 0;
918                 }
919         }
920
921         if (!is_valid) {
922                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/moh\n");
923                 ast_ari_response_error(response, 500,
924                         "Internal Server Error", "Response validation failed");
925         }
926 #endif /* AST_DEVMODE */
927
928 fin: __attribute__((unused))
929         return;
930 }
931 /*!
932  * \brief Parameter parsing callback for /channels/{channelId}/play.
933  * \param get_params GET parameters in the HTTP request.
934  * \param path_vars Path variables extracted from the request.
935  * \param headers HTTP headers.
936  * \param[out] response Response to the HTTP request.
937  */
938 static void ast_ari_channels_play_cb(
939         struct ast_variable *get_params, struct ast_variable *path_vars,
940         struct ast_variable *headers, struct ast_ari_response *response)
941 {
942         struct ast_ari_channels_play_args args = {};
943         struct ast_variable *i;
944 #if defined(AST_DEVMODE)
945         int is_valid;
946         int code;
947 #endif /* AST_DEVMODE */
948
949         for (i = get_params; i; i = i->next) {
950                 if (strcmp(i->name, "media") == 0) {
951                         args.media = (i->value);
952                 } else
953                 if (strcmp(i->name, "lang") == 0) {
954                         args.lang = (i->value);
955                 } else
956                 if (strcmp(i->name, "offsetms") == 0) {
957                         args.offsetms = atoi(i->value);
958                 } else
959                 if (strcmp(i->name, "skipms") == 0) {
960                         args.skipms = atoi(i->value);
961                 } else
962                 {}
963         }
964         for (i = path_vars; i; i = i->next) {
965                 if (strcmp(i->name, "channelId") == 0) {
966                         args.channel_id = (i->value);
967                 } else
968                 {}
969         }
970         ast_ari_channels_play(headers, &args, response);
971 #if defined(AST_DEVMODE)
972         code = response->response_code;
973
974         switch (code) {
975         case 0: /* Implementation is still a stub, or the code wasn't set */
976                 is_valid = response->message == NULL;
977                 break;
978         case 500: /* Internal Server Error */
979         case 501: /* Not Implemented */
980         case 404: /* Channel not found */
981         case 409: /* Channel not in a Stasis application */
982                 is_valid = 1;
983                 break;
984         default:
985                 if (200 <= code && code <= 299) {
986                         is_valid = ast_ari_validate_playback(
987                                 response->message);
988                 } else {
989                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/play\n", code);
990                         is_valid = 0;
991                 }
992         }
993
994         if (!is_valid) {
995                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/play\n");
996                 ast_ari_response_error(response, 500,
997                         "Internal Server Error", "Response validation failed");
998         }
999 #endif /* AST_DEVMODE */
1000
1001 fin: __attribute__((unused))
1002         return;
1003 }
1004 /*!
1005  * \brief Parameter parsing callback for /channels/{channelId}/record.
1006  * \param get_params GET parameters in the HTTP request.
1007  * \param path_vars Path variables extracted from the request.
1008  * \param headers HTTP headers.
1009  * \param[out] response Response to the HTTP request.
1010  */
1011 static void ast_ari_channels_record_cb(
1012         struct ast_variable *get_params, struct ast_variable *path_vars,
1013         struct ast_variable *headers, struct ast_ari_response *response)
1014 {
1015         struct ast_ari_channels_record_args args = {};
1016         struct ast_variable *i;
1017 #if defined(AST_DEVMODE)
1018         int is_valid;
1019         int code;
1020 #endif /* AST_DEVMODE */
1021
1022         for (i = get_params; i; i = i->next) {
1023                 if (strcmp(i->name, "name") == 0) {
1024                         args.name = (i->value);
1025                 } else
1026                 if (strcmp(i->name, "format") == 0) {
1027                         args.format = (i->value);
1028                 } else
1029                 if (strcmp(i->name, "maxDurationSeconds") == 0) {
1030                         args.max_duration_seconds = atoi(i->value);
1031                 } else
1032                 if (strcmp(i->name, "maxSilenceSeconds") == 0) {
1033                         args.max_silence_seconds = atoi(i->value);
1034                 } else
1035                 if (strcmp(i->name, "ifExists") == 0) {
1036                         args.if_exists = (i->value);
1037                 } else
1038                 if (strcmp(i->name, "beep") == 0) {
1039                         args.beep = ast_true(i->value);
1040                 } else
1041                 if (strcmp(i->name, "terminateOn") == 0) {
1042                         args.terminate_on = (i->value);
1043                 } else
1044                 {}
1045         }
1046         for (i = path_vars; i; i = i->next) {
1047                 if (strcmp(i->name, "channelId") == 0) {
1048                         args.channel_id = (i->value);
1049                 } else
1050                 {}
1051         }
1052         ast_ari_channels_record(headers, &args, response);
1053 #if defined(AST_DEVMODE)
1054         code = response->response_code;
1055
1056         switch (code) {
1057         case 0: /* Implementation is still a stub, or the code wasn't set */
1058                 is_valid = response->message == NULL;
1059                 break;
1060         case 500: /* Internal Server Error */
1061         case 501: /* Not Implemented */
1062         case 400: /* Invalid parameters */
1063         case 404: /* Channel not found */
1064         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 */
1065         case 422: /* The format specified is unknown on this system */
1066                 is_valid = 1;
1067                 break;
1068         default:
1069                 if (200 <= code && code <= 299) {
1070                         is_valid = ast_ari_validate_live_recording(
1071                                 response->message);
1072                 } else {
1073                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/record\n", code);
1074                         is_valid = 0;
1075                 }
1076         }
1077
1078         if (!is_valid) {
1079                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/record\n");
1080                 ast_ari_response_error(response, 500,
1081                         "Internal Server Error", "Response validation failed");
1082         }
1083 #endif /* AST_DEVMODE */
1084
1085 fin: __attribute__((unused))
1086         return;
1087 }
1088 /*!
1089  * \brief Parameter parsing callback for /channels/{channelId}/variable.
1090  * \param get_params GET parameters in the HTTP request.
1091  * \param path_vars Path variables extracted from the request.
1092  * \param headers HTTP headers.
1093  * \param[out] response Response to the HTTP request.
1094  */
1095 static void ast_ari_channels_get_channel_var_cb(
1096         struct ast_variable *get_params, struct ast_variable *path_vars,
1097         struct ast_variable *headers, struct ast_ari_response *response)
1098 {
1099         struct ast_ari_channels_get_channel_var_args args = {};
1100         struct ast_variable *i;
1101 #if defined(AST_DEVMODE)
1102         int is_valid;
1103         int code;
1104 #endif /* AST_DEVMODE */
1105
1106         for (i = get_params; i; i = i->next) {
1107                 if (strcmp(i->name, "variable") == 0) {
1108                         args.variable = (i->value);
1109                 } else
1110                 {}
1111         }
1112         for (i = path_vars; i; i = i->next) {
1113                 if (strcmp(i->name, "channelId") == 0) {
1114                         args.channel_id = (i->value);
1115                 } else
1116                 {}
1117         }
1118         ast_ari_channels_get_channel_var(headers, &args, response);
1119 #if defined(AST_DEVMODE)
1120         code = response->response_code;
1121
1122         switch (code) {
1123         case 0: /* Implementation is still a stub, or the code wasn't set */
1124                 is_valid = response->message == NULL;
1125                 break;
1126         case 500: /* Internal Server Error */
1127         case 501: /* Not Implemented */
1128         case 400: /* Missing variable parameter. */
1129         case 404: /* Channel not found */
1130         case 409: /* Channel not in a Stasis application */
1131                 is_valid = 1;
1132                 break;
1133         default:
1134                 if (200 <= code && code <= 299) {
1135                         is_valid = ast_ari_validate_variable(
1136                                 response->message);
1137                 } else {
1138                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/variable\n", code);
1139                         is_valid = 0;
1140                 }
1141         }
1142
1143         if (!is_valid) {
1144                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/variable\n");
1145                 ast_ari_response_error(response, 500,
1146                         "Internal Server Error", "Response validation failed");
1147         }
1148 #endif /* AST_DEVMODE */
1149
1150 fin: __attribute__((unused))
1151         return;
1152 }
1153 /*!
1154  * \brief Parameter parsing callback for /channels/{channelId}/variable.
1155  * \param get_params GET parameters in the HTTP request.
1156  * \param path_vars Path variables extracted from the request.
1157  * \param headers HTTP headers.
1158  * \param[out] response Response to the HTTP request.
1159  */
1160 static void ast_ari_channels_set_channel_var_cb(
1161         struct ast_variable *get_params, struct ast_variable *path_vars,
1162         struct ast_variable *headers, struct ast_ari_response *response)
1163 {
1164         struct ast_ari_channels_set_channel_var_args args = {};
1165         struct ast_variable *i;
1166 #if defined(AST_DEVMODE)
1167         int is_valid;
1168         int code;
1169 #endif /* AST_DEVMODE */
1170
1171         for (i = get_params; i; i = i->next) {
1172                 if (strcmp(i->name, "variable") == 0) {
1173                         args.variable = (i->value);
1174                 } else
1175                 if (strcmp(i->name, "value") == 0) {
1176                         args.value = (i->value);
1177                 } else
1178                 {}
1179         }
1180         for (i = path_vars; i; i = i->next) {
1181                 if (strcmp(i->name, "channelId") == 0) {
1182                         args.channel_id = (i->value);
1183                 } else
1184                 {}
1185         }
1186         ast_ari_channels_set_channel_var(headers, &args, response);
1187 #if defined(AST_DEVMODE)
1188         code = response->response_code;
1189
1190         switch (code) {
1191         case 0: /* Implementation is still a stub, or the code wasn't set */
1192                 is_valid = response->message == NULL;
1193                 break;
1194         case 500: /* Internal Server Error */
1195         case 501: /* Not Implemented */
1196         case 400: /* Missing variable parameter. */
1197         case 404: /* Channel not found */
1198         case 409: /* Channel not in a Stasis application */
1199                 is_valid = 1;
1200                 break;
1201         default:
1202                 if (200 <= code && code <= 299) {
1203                         is_valid = ast_ari_validate_void(
1204                                 response->message);
1205                 } else {
1206                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/variable\n", code);
1207                         is_valid = 0;
1208                 }
1209         }
1210
1211         if (!is_valid) {
1212                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/variable\n");
1213                 ast_ari_response_error(response, 500,
1214                         "Internal Server Error", "Response validation failed");
1215         }
1216 #endif /* AST_DEVMODE */
1217
1218 fin: __attribute__((unused))
1219         return;
1220 }
1221
1222 /*! \brief REST handler for /api-docs/channels.{format} */
1223 static struct stasis_rest_handlers channels_channelId_continue = {
1224         .path_segment = "continue",
1225         .callbacks = {
1226                 [AST_HTTP_POST] = ast_ari_channels_continue_in_dialplan_cb,
1227         },
1228         .num_children = 0,
1229         .children = {  }
1230 };
1231 /*! \brief REST handler for /api-docs/channels.{format} */
1232 static struct stasis_rest_handlers channels_channelId_answer = {
1233         .path_segment = "answer",
1234         .callbacks = {
1235                 [AST_HTTP_POST] = ast_ari_channels_answer_cb,
1236         },
1237         .num_children = 0,
1238         .children = {  }
1239 };
1240 /*! \brief REST handler for /api-docs/channels.{format} */
1241 static struct stasis_rest_handlers channels_channelId_ring = {
1242         .path_segment = "ring",
1243         .callbacks = {
1244                 [AST_HTTP_POST] = ast_ari_channels_ring_cb,
1245         },
1246         .num_children = 0,
1247         .children = {  }
1248 };
1249 /*! \brief REST handler for /api-docs/channels.{format} */
1250 static struct stasis_rest_handlers channels_channelId_dtmf = {
1251         .path_segment = "dtmf",
1252         .callbacks = {
1253                 [AST_HTTP_POST] = ast_ari_channels_send_dtmf_cb,
1254         },
1255         .num_children = 0,
1256         .children = {  }
1257 };
1258 /*! \brief REST handler for /api-docs/channels.{format} */
1259 static struct stasis_rest_handlers channels_channelId_mute = {
1260         .path_segment = "mute",
1261         .callbacks = {
1262                 [AST_HTTP_POST] = ast_ari_channels_mute_cb,
1263                 [AST_HTTP_DELETE] = ast_ari_channels_unmute_cb,
1264         },
1265         .num_children = 0,
1266         .children = {  }
1267 };
1268 /*! \brief REST handler for /api-docs/channels.{format} */
1269 static struct stasis_rest_handlers channels_channelId_hold = {
1270         .path_segment = "hold",
1271         .callbacks = {
1272                 [AST_HTTP_POST] = ast_ari_channels_hold_cb,
1273                 [AST_HTTP_DELETE] = ast_ari_channels_unhold_cb,
1274         },
1275         .num_children = 0,
1276         .children = {  }
1277 };
1278 /*! \brief REST handler for /api-docs/channels.{format} */
1279 static struct stasis_rest_handlers channels_channelId_moh = {
1280         .path_segment = "moh",
1281         .callbacks = {
1282                 [AST_HTTP_POST] = ast_ari_channels_start_moh_cb,
1283                 [AST_HTTP_DELETE] = ast_ari_channels_stop_moh_cb,
1284         },
1285         .num_children = 0,
1286         .children = {  }
1287 };
1288 /*! \brief REST handler for /api-docs/channels.{format} */
1289 static struct stasis_rest_handlers channels_channelId_play = {
1290         .path_segment = "play",
1291         .callbacks = {
1292                 [AST_HTTP_POST] = ast_ari_channels_play_cb,
1293         },
1294         .num_children = 0,
1295         .children = {  }
1296 };
1297 /*! \brief REST handler for /api-docs/channels.{format} */
1298 static struct stasis_rest_handlers channels_channelId_record = {
1299         .path_segment = "record",
1300         .callbacks = {
1301                 [AST_HTTP_POST] = ast_ari_channels_record_cb,
1302         },
1303         .num_children = 0,
1304         .children = {  }
1305 };
1306 /*! \brief REST handler for /api-docs/channels.{format} */
1307 static struct stasis_rest_handlers channels_channelId_variable = {
1308         .path_segment = "variable",
1309         .callbacks = {
1310                 [AST_HTTP_GET] = ast_ari_channels_get_channel_var_cb,
1311                 [AST_HTTP_POST] = ast_ari_channels_set_channel_var_cb,
1312         },
1313         .num_children = 0,
1314         .children = {  }
1315 };
1316 /*! \brief REST handler for /api-docs/channels.{format} */
1317 static struct stasis_rest_handlers channels_channelId = {
1318         .path_segment = "channelId",
1319         .is_wildcard = 1,
1320         .callbacks = {
1321                 [AST_HTTP_GET] = ast_ari_channels_get_cb,
1322                 [AST_HTTP_DELETE] = ast_ari_channels_hangup_cb,
1323         },
1324         .num_children = 10,
1325         .children = { &channels_channelId_continue,&channels_channelId_answer,&channels_channelId_ring,&channels_channelId_dtmf,&channels_channelId_mute,&channels_channelId_hold,&channels_channelId_moh,&channels_channelId_play,&channels_channelId_record,&channels_channelId_variable, }
1326 };
1327 /*! \brief REST handler for /api-docs/channels.{format} */
1328 static struct stasis_rest_handlers channels = {
1329         .path_segment = "channels",
1330         .callbacks = {
1331                 [AST_HTTP_GET] = ast_ari_channels_list_cb,
1332                 [AST_HTTP_POST] = ast_ari_channels_originate_cb,
1333         },
1334         .num_children = 1,
1335         .children = { &channels_channelId, }
1336 };
1337
1338 static int load_module(void)
1339 {
1340         int res = 0;
1341         stasis_app_ref();
1342         res |= ast_ari_add_handler(&channels);
1343         return res;
1344 }
1345
1346 static int unload_module(void)
1347 {
1348         ast_ari_remove_handler(&channels);
1349         stasis_app_unref();
1350         return 0;
1351 }
1352
1353 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "RESTful API module - Channel resources",
1354         .load = load_module,
1355         .unload = unload_module,
1356         .nonoptreq = "res_ari,res_stasis",
1357         );