806c370edae900990b4ade0f1f64a370ee061c28
[asterisk/asterisk.git] / res / res_stasis_http_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_stasis_http_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_stasis_http</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 "stasis_http/resource_channels.h"
47 #if defined(AST_DEVMODE)
48 #include "stasis_http/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 stasis_http_get_channels_cb(
59         struct ast_variable *get_params, struct ast_variable *path_vars,
60         struct ast_variable *headers, struct stasis_http_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         stasis_http_get_channels(headers, &args, response);
69 #if defined(AST_DEVMODE)
70         code = response->response_code;
71
72         switch (code) {
73         case 500: /* Internal server error */
74                 is_valid = 1;
75                 break;
76         default:
77                 if (200 <= code && code <= 299) {
78                         is_valid = ari_validate_list(response->message,
79                                 ari_validate_channel_fn());
80                 } else {
81                         ast_log(LOG_ERROR, "Invalid error response %d for /channels\n", code);
82                         is_valid = 0;
83                 }
84         }
85
86         if (!is_valid) {
87                 ast_log(LOG_ERROR, "Response validation failed for /channels\n");
88                 stasis_http_response_error(response, 500,
89                         "Internal Server Error", "Response validation failed");
90         }
91 #endif /* AST_DEVMODE */
92 }
93 /*!
94  * \brief Parameter parsing callback for /channels.
95  * \param get_params GET parameters in the HTTP request.
96  * \param path_vars Path variables extracted from the request.
97  * \param headers HTTP headers.
98  * \param[out] response Response to the HTTP request.
99  */
100 static void stasis_http_originate_cb(
101         struct ast_variable *get_params, struct ast_variable *path_vars,
102         struct ast_variable *headers, struct stasis_http_response *response)
103 {
104 #if defined(AST_DEVMODE)
105         int is_valid;
106         int code;
107 #endif /* AST_DEVMODE */
108
109         struct ast_originate_args args = {};
110         struct ast_variable *i;
111
112         for (i = get_params; i; i = i->next) {
113                 if (strcmp(i->name, "endpoint") == 0) {
114                         args.endpoint = (i->value);
115                 } else
116                 if (strcmp(i->name, "extension") == 0) {
117                         args.extension = (i->value);
118                 } else
119                 if (strcmp(i->name, "context") == 0) {
120                         args.context = (i->value);
121                 } else
122                 if (strcmp(i->name, "priority") == 0) {
123                         args.priority = atol(i->value);
124                 } else
125                 if (strcmp(i->name, "app") == 0) {
126                         args.app = (i->value);
127                 } else
128                 if (strcmp(i->name, "appArgs") == 0) {
129                         args.app_args = (i->value);
130                 } else
131                 if (strcmp(i->name, "callerId") == 0) {
132                         args.caller_id = (i->value);
133                 } else
134                 if (strcmp(i->name, "timeout") == 0) {
135                         args.timeout = atoi(i->value);
136                 } else
137                 {}
138         }
139         stasis_http_originate(headers, &args, response);
140 #if defined(AST_DEVMODE)
141         code = response->response_code;
142
143         switch (code) {
144         case 500: /* Internal server error */
145         case 400: /* Invalid parameters for originating a channel. */
146                 is_valid = 1;
147                 break;
148         default:
149                 if (200 <= code && code <= 299) {
150                         is_valid = ari_validate_void(
151                                 response->message);
152                 } else {
153                         ast_log(LOG_ERROR, "Invalid error response %d for /channels\n", code);
154                         is_valid = 0;
155                 }
156         }
157
158         if (!is_valid) {
159                 ast_log(LOG_ERROR, "Response validation failed for /channels\n");
160                 stasis_http_response_error(response, 500,
161                         "Internal Server Error", "Response validation failed");
162         }
163 #endif /* AST_DEVMODE */
164 }
165 /*!
166  * \brief Parameter parsing callback for /channels/{channelId}.
167  * \param get_params GET parameters in the HTTP request.
168  * \param path_vars Path variables extracted from the request.
169  * \param headers HTTP headers.
170  * \param[out] response Response to the HTTP request.
171  */
172 static void stasis_http_get_channel_cb(
173         struct ast_variable *get_params, struct ast_variable *path_vars,
174         struct ast_variable *headers, struct stasis_http_response *response)
175 {
176 #if defined(AST_DEVMODE)
177         int is_valid;
178         int code;
179 #endif /* AST_DEVMODE */
180
181         struct ast_get_channel_args args = {};
182         struct ast_variable *i;
183
184         for (i = path_vars; i; i = i->next) {
185                 if (strcmp(i->name, "channelId") == 0) {
186                         args.channel_id = (i->value);
187                 } else
188                 {}
189         }
190         stasis_http_get_channel(headers, &args, response);
191 #if defined(AST_DEVMODE)
192         code = response->response_code;
193
194         switch (code) {
195         case 500: /* Internal server error */
196         case 404: /* Channel not found */
197                 is_valid = 1;
198                 break;
199         default:
200                 if (200 <= code && code <= 299) {
201                         is_valid = ari_validate_channel(
202                                 response->message);
203                 } else {
204                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}\n", code);
205                         is_valid = 0;
206                 }
207         }
208
209         if (!is_valid) {
210                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}\n");
211                 stasis_http_response_error(response, 500,
212                         "Internal Server Error", "Response validation failed");
213         }
214 #endif /* AST_DEVMODE */
215 }
216 /*!
217  * \brief Parameter parsing callback for /channels/{channelId}.
218  * \param get_params GET parameters in the HTTP request.
219  * \param path_vars Path variables extracted from the request.
220  * \param headers HTTP headers.
221  * \param[out] response Response to the HTTP request.
222  */
223 static void stasis_http_delete_channel_cb(
224         struct ast_variable *get_params, struct ast_variable *path_vars,
225         struct ast_variable *headers, struct stasis_http_response *response)
226 {
227 #if defined(AST_DEVMODE)
228         int is_valid;
229         int code;
230 #endif /* AST_DEVMODE */
231
232         struct ast_delete_channel_args args = {};
233         struct ast_variable *i;
234
235         for (i = path_vars; i; i = i->next) {
236                 if (strcmp(i->name, "channelId") == 0) {
237                         args.channel_id = (i->value);
238                 } else
239                 {}
240         }
241         stasis_http_delete_channel(headers, &args, response);
242 #if defined(AST_DEVMODE)
243         code = response->response_code;
244
245         switch (code) {
246         case 500: /* Internal server error */
247         case 404: /* Channel not found */
248                 is_valid = 1;
249                 break;
250         default:
251                 if (200 <= code && code <= 299) {
252                         is_valid = ari_validate_void(
253                                 response->message);
254                 } else {
255                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}\n", code);
256                         is_valid = 0;
257                 }
258         }
259
260         if (!is_valid) {
261                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}\n");
262                 stasis_http_response_error(response, 500,
263                         "Internal Server Error", "Response validation failed");
264         }
265 #endif /* AST_DEVMODE */
266 }
267 /*!
268  * \brief Parameter parsing callback for /channels/{channelId}/dial.
269  * \param get_params GET parameters in the HTTP request.
270  * \param path_vars Path variables extracted from the request.
271  * \param headers HTTP headers.
272  * \param[out] response Response to the HTTP request.
273  */
274 static void stasis_http_dial_cb(
275         struct ast_variable *get_params, struct ast_variable *path_vars,
276         struct ast_variable *headers, struct stasis_http_response *response)
277 {
278 #if defined(AST_DEVMODE)
279         int is_valid;
280         int code;
281 #endif /* AST_DEVMODE */
282
283         struct ast_dial_args args = {};
284         struct ast_variable *i;
285
286         for (i = get_params; i; i = i->next) {
287                 if (strcmp(i->name, "endpoint") == 0) {
288                         args.endpoint = (i->value);
289                 } else
290                 if (strcmp(i->name, "extension") == 0) {
291                         args.extension = (i->value);
292                 } else
293                 if (strcmp(i->name, "context") == 0) {
294                         args.context = (i->value);
295                 } else
296                 if (strcmp(i->name, "timeout") == 0) {
297                         args.timeout = atoi(i->value);
298                 } else
299                 {}
300         }
301         for (i = path_vars; i; i = i->next) {
302                 if (strcmp(i->name, "channelId") == 0) {
303                         args.channel_id = (i->value);
304                 } else
305                 {}
306         }
307         stasis_http_dial(headers, &args, response);
308 #if defined(AST_DEVMODE)
309         code = response->response_code;
310
311         switch (code) {
312         case 500: /* Internal server error */
313         case 404: /* Channel not found */
314         case 409: /* Channel not in a Stasis application */
315                 is_valid = 1;
316                 break;
317         default:
318                 if (200 <= code && code <= 299) {
319                         is_valid = ari_validate_dialed(
320                                 response->message);
321                 } else {
322                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/dial\n", code);
323                         is_valid = 0;
324                 }
325         }
326
327         if (!is_valid) {
328                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/dial\n");
329                 stasis_http_response_error(response, 500,
330                         "Internal Server Error", "Response validation failed");
331         }
332 #endif /* AST_DEVMODE */
333 }
334 /*!
335  * \brief Parameter parsing callback for /channels/{channelId}/continue.
336  * \param get_params GET parameters in the HTTP request.
337  * \param path_vars Path variables extracted from the request.
338  * \param headers HTTP headers.
339  * \param[out] response Response to the HTTP request.
340  */
341 static void stasis_http_continue_in_dialplan_cb(
342         struct ast_variable *get_params, struct ast_variable *path_vars,
343         struct ast_variable *headers, struct stasis_http_response *response)
344 {
345 #if defined(AST_DEVMODE)
346         int is_valid;
347         int code;
348 #endif /* AST_DEVMODE */
349
350         struct ast_continue_in_dialplan_args args = {};
351         struct ast_variable *i;
352
353         for (i = get_params; i; i = i->next) {
354                 if (strcmp(i->name, "context") == 0) {
355                         args.context = (i->value);
356                 } else
357                 if (strcmp(i->name, "extension") == 0) {
358                         args.extension = (i->value);
359                 } else
360                 if (strcmp(i->name, "priority") == 0) {
361                         args.priority = atoi(i->value);
362                 } else
363                 {}
364         }
365         for (i = path_vars; i; i = i->next) {
366                 if (strcmp(i->name, "channelId") == 0) {
367                         args.channel_id = (i->value);
368                 } else
369                 {}
370         }
371         stasis_http_continue_in_dialplan(headers, &args, response);
372 #if defined(AST_DEVMODE)
373         code = response->response_code;
374
375         switch (code) {
376         case 500: /* Internal server error */
377         case 404: /* Channel not found */
378         case 409: /* Channel not in a Stasis application */
379                 is_valid = 1;
380                 break;
381         default:
382                 if (200 <= code && code <= 299) {
383                         is_valid = ari_validate_void(
384                                 response->message);
385                 } else {
386                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/continue\n", code);
387                         is_valid = 0;
388                 }
389         }
390
391         if (!is_valid) {
392                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/continue\n");
393                 stasis_http_response_error(response, 500,
394                         "Internal Server Error", "Response validation failed");
395         }
396 #endif /* AST_DEVMODE */
397 }
398 /*!
399  * \brief Parameter parsing callback for /channels/{channelId}/answer.
400  * \param get_params GET parameters in the HTTP request.
401  * \param path_vars Path variables extracted from the request.
402  * \param headers HTTP headers.
403  * \param[out] response Response to the HTTP request.
404  */
405 static void stasis_http_answer_channel_cb(
406         struct ast_variable *get_params, struct ast_variable *path_vars,
407         struct ast_variable *headers, struct stasis_http_response *response)
408 {
409 #if defined(AST_DEVMODE)
410         int is_valid;
411         int code;
412 #endif /* AST_DEVMODE */
413
414         struct ast_answer_channel_args args = {};
415         struct ast_variable *i;
416
417         for (i = path_vars; i; i = i->next) {
418                 if (strcmp(i->name, "channelId") == 0) {
419                         args.channel_id = (i->value);
420                 } else
421                 {}
422         }
423         stasis_http_answer_channel(headers, &args, response);
424 #if defined(AST_DEVMODE)
425         code = response->response_code;
426
427         switch (code) {
428         case 500: /* Internal server error */
429         case 404: /* Channel not found */
430         case 409: /* Channel not in a Stasis application */
431                 is_valid = 1;
432                 break;
433         default:
434                 if (200 <= code && code <= 299) {
435                         is_valid = ari_validate_void(
436                                 response->message);
437                 } else {
438                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/answer\n", code);
439                         is_valid = 0;
440                 }
441         }
442
443         if (!is_valid) {
444                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/answer\n");
445                 stasis_http_response_error(response, 500,
446                         "Internal Server Error", "Response validation failed");
447         }
448 #endif /* AST_DEVMODE */
449 }
450 /*!
451  * \brief Parameter parsing callback for /channels/{channelId}/mute.
452  * \param get_params GET parameters in the HTTP request.
453  * \param path_vars Path variables extracted from the request.
454  * \param headers HTTP headers.
455  * \param[out] response Response to the HTTP request.
456  */
457 static void stasis_http_mute_channel_cb(
458         struct ast_variable *get_params, struct ast_variable *path_vars,
459         struct ast_variable *headers, struct stasis_http_response *response)
460 {
461 #if defined(AST_DEVMODE)
462         int is_valid;
463         int code;
464 #endif /* AST_DEVMODE */
465
466         struct ast_mute_channel_args args = {};
467         struct ast_variable *i;
468
469         for (i = get_params; i; i = i->next) {
470                 if (strcmp(i->name, "direction") == 0) {
471                         args.direction = (i->value);
472                 } else
473                 {}
474         }
475         for (i = path_vars; i; i = i->next) {
476                 if (strcmp(i->name, "channelId") == 0) {
477                         args.channel_id = (i->value);
478                 } else
479                 {}
480         }
481         stasis_http_mute_channel(headers, &args, response);
482 #if defined(AST_DEVMODE)
483         code = response->response_code;
484
485         switch (code) {
486         case 500: /* Internal server error */
487         case 404: /* Channel not found */
488         case 409: /* Channel not in a Stasis application */
489                 is_valid = 1;
490                 break;
491         default:
492                 if (200 <= code && code <= 299) {
493                         is_valid = ari_validate_void(
494                                 response->message);
495                 } else {
496                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/mute\n", code);
497                         is_valid = 0;
498                 }
499         }
500
501         if (!is_valid) {
502                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/mute\n");
503                 stasis_http_response_error(response, 500,
504                         "Internal Server Error", "Response validation failed");
505         }
506 #endif /* AST_DEVMODE */
507 }
508 /*!
509  * \brief Parameter parsing callback for /channels/{channelId}/unmute.
510  * \param get_params GET parameters in the HTTP request.
511  * \param path_vars Path variables extracted from the request.
512  * \param headers HTTP headers.
513  * \param[out] response Response to the HTTP request.
514  */
515 static void stasis_http_unmute_channel_cb(
516         struct ast_variable *get_params, struct ast_variable *path_vars,
517         struct ast_variable *headers, struct stasis_http_response *response)
518 {
519 #if defined(AST_DEVMODE)
520         int is_valid;
521         int code;
522 #endif /* AST_DEVMODE */
523
524         struct ast_unmute_channel_args args = {};
525         struct ast_variable *i;
526
527         for (i = get_params; i; i = i->next) {
528                 if (strcmp(i->name, "direction") == 0) {
529                         args.direction = (i->value);
530                 } else
531                 {}
532         }
533         for (i = path_vars; i; i = i->next) {
534                 if (strcmp(i->name, "channelId") == 0) {
535                         args.channel_id = (i->value);
536                 } else
537                 {}
538         }
539         stasis_http_unmute_channel(headers, &args, response);
540 #if defined(AST_DEVMODE)
541         code = response->response_code;
542
543         switch (code) {
544         case 500: /* Internal server error */
545         case 404: /* Channel not found */
546         case 409: /* Channel not in a Stasis application */
547                 is_valid = 1;
548                 break;
549         default:
550                 if (200 <= code && code <= 299) {
551                         is_valid = ari_validate_void(
552                                 response->message);
553                 } else {
554                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/unmute\n", code);
555                         is_valid = 0;
556                 }
557         }
558
559         if (!is_valid) {
560                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/unmute\n");
561                 stasis_http_response_error(response, 500,
562                         "Internal Server Error", "Response validation failed");
563         }
564 #endif /* AST_DEVMODE */
565 }
566 /*!
567  * \brief Parameter parsing callback for /channels/{channelId}/hold.
568  * \param get_params GET parameters in the HTTP request.
569  * \param path_vars Path variables extracted from the request.
570  * \param headers HTTP headers.
571  * \param[out] response Response to the HTTP request.
572  */
573 static void stasis_http_hold_channel_cb(
574         struct ast_variable *get_params, struct ast_variable *path_vars,
575         struct ast_variable *headers, struct stasis_http_response *response)
576 {
577 #if defined(AST_DEVMODE)
578         int is_valid;
579         int code;
580 #endif /* AST_DEVMODE */
581
582         struct ast_hold_channel_args args = {};
583         struct ast_variable *i;
584
585         for (i = path_vars; i; i = i->next) {
586                 if (strcmp(i->name, "channelId") == 0) {
587                         args.channel_id = (i->value);
588                 } else
589                 {}
590         }
591         stasis_http_hold_channel(headers, &args, response);
592 #if defined(AST_DEVMODE)
593         code = response->response_code;
594
595         switch (code) {
596         case 500: /* Internal server error */
597         case 404: /* Channel not found */
598         case 409: /* Channel not in a Stasis application */
599                 is_valid = 1;
600                 break;
601         default:
602                 if (200 <= code && code <= 299) {
603                         is_valid = ari_validate_void(
604                                 response->message);
605                 } else {
606                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/hold\n", code);
607                         is_valid = 0;
608                 }
609         }
610
611         if (!is_valid) {
612                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/hold\n");
613                 stasis_http_response_error(response, 500,
614                         "Internal Server Error", "Response validation failed");
615         }
616 #endif /* AST_DEVMODE */
617 }
618 /*!
619  * \brief Parameter parsing callback for /channels/{channelId}/unhold.
620  * \param get_params GET parameters in the HTTP request.
621  * \param path_vars Path variables extracted from the request.
622  * \param headers HTTP headers.
623  * \param[out] response Response to the HTTP request.
624  */
625 static void stasis_http_unhold_channel_cb(
626         struct ast_variable *get_params, struct ast_variable *path_vars,
627         struct ast_variable *headers, struct stasis_http_response *response)
628 {
629 #if defined(AST_DEVMODE)
630         int is_valid;
631         int code;
632 #endif /* AST_DEVMODE */
633
634         struct ast_unhold_channel_args args = {};
635         struct ast_variable *i;
636
637         for (i = path_vars; i; i = i->next) {
638                 if (strcmp(i->name, "channelId") == 0) {
639                         args.channel_id = (i->value);
640                 } else
641                 {}
642         }
643         stasis_http_unhold_channel(headers, &args, response);
644 #if defined(AST_DEVMODE)
645         code = response->response_code;
646
647         switch (code) {
648         case 500: /* Internal server error */
649         case 404: /* Channel not found */
650         case 409: /* Channel not in a Stasis application */
651                 is_valid = 1;
652                 break;
653         default:
654                 if (200 <= code && code <= 299) {
655                         is_valid = ari_validate_void(
656                                 response->message);
657                 } else {
658                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/unhold\n", code);
659                         is_valid = 0;
660                 }
661         }
662
663         if (!is_valid) {
664                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/unhold\n");
665                 stasis_http_response_error(response, 500,
666                         "Internal Server Error", "Response validation failed");
667         }
668 #endif /* AST_DEVMODE */
669 }
670 /*!
671  * \brief Parameter parsing callback for /channels/{channelId}/play.
672  * \param get_params GET parameters in the HTTP request.
673  * \param path_vars Path variables extracted from the request.
674  * \param headers HTTP headers.
675  * \param[out] response Response to the HTTP request.
676  */
677 static void stasis_http_play_on_channel_cb(
678         struct ast_variable *get_params, struct ast_variable *path_vars,
679         struct ast_variable *headers, struct stasis_http_response *response)
680 {
681 #if defined(AST_DEVMODE)
682         int is_valid;
683         int code;
684 #endif /* AST_DEVMODE */
685
686         struct ast_play_on_channel_args args = {};
687         struct ast_variable *i;
688
689         for (i = get_params; i; i = i->next) {
690                 if (strcmp(i->name, "media") == 0) {
691                         args.media = (i->value);
692                 } else
693                 if (strcmp(i->name, "lang") == 0) {
694                         args.lang = (i->value);
695                 } else
696                 if (strcmp(i->name, "offsetms") == 0) {
697                         args.offsetms = atoi(i->value);
698                 } else
699                 if (strcmp(i->name, "skipms") == 0) {
700                         args.skipms = atoi(i->value);
701                 } else
702                 {}
703         }
704         for (i = path_vars; i; i = i->next) {
705                 if (strcmp(i->name, "channelId") == 0) {
706                         args.channel_id = (i->value);
707                 } else
708                 {}
709         }
710         stasis_http_play_on_channel(headers, &args, response);
711 #if defined(AST_DEVMODE)
712         code = response->response_code;
713
714         switch (code) {
715         case 500: /* Internal server error */
716         case 404: /* Channel not found */
717         case 409: /* Channel not in a Stasis application */
718                 is_valid = 1;
719                 break;
720         default:
721                 if (200 <= code && code <= 299) {
722                         is_valid = ari_validate_playback(
723                                 response->message);
724                 } else {
725                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/play\n", code);
726                         is_valid = 0;
727                 }
728         }
729
730         if (!is_valid) {
731                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/play\n");
732                 stasis_http_response_error(response, 500,
733                         "Internal Server Error", "Response validation failed");
734         }
735 #endif /* AST_DEVMODE */
736 }
737 /*!
738  * \brief Parameter parsing callback for /channels/{channelId}/record.
739  * \param get_params GET parameters in the HTTP request.
740  * \param path_vars Path variables extracted from the request.
741  * \param headers HTTP headers.
742  * \param[out] response Response to the HTTP request.
743  */
744 static void stasis_http_record_channel_cb(
745         struct ast_variable *get_params, struct ast_variable *path_vars,
746         struct ast_variable *headers, struct stasis_http_response *response)
747 {
748 #if defined(AST_DEVMODE)
749         int is_valid;
750         int code;
751 #endif /* AST_DEVMODE */
752
753         struct ast_record_channel_args args = {};
754         struct ast_variable *i;
755
756         for (i = get_params; i; i = i->next) {
757                 if (strcmp(i->name, "name") == 0) {
758                         args.name = (i->value);
759                 } else
760                 if (strcmp(i->name, "format") == 0) {
761                         args.format = (i->value);
762                 } else
763                 if (strcmp(i->name, "maxDurationSeconds") == 0) {
764                         args.max_duration_seconds = atoi(i->value);
765                 } else
766                 if (strcmp(i->name, "maxSilenceSeconds") == 0) {
767                         args.max_silence_seconds = atoi(i->value);
768                 } else
769                 if (strcmp(i->name, "ifExists") == 0) {
770                         args.if_exists = (i->value);
771                 } else
772                 if (strcmp(i->name, "beep") == 0) {
773                         args.beep = ast_true(i->value);
774                 } else
775                 if (strcmp(i->name, "terminateOn") == 0) {
776                         args.terminate_on = (i->value);
777                 } else
778                 {}
779         }
780         for (i = path_vars; i; i = i->next) {
781                 if (strcmp(i->name, "channelId") == 0) {
782                         args.channel_id = (i->value);
783                 } else
784                 {}
785         }
786         stasis_http_record_channel(headers, &args, response);
787 #if defined(AST_DEVMODE)
788         code = response->response_code;
789
790         switch (code) {
791         case 500: /* Internal server error */
792         case 400: /* Invalid parameters */
793         case 404: /* Channel not found */
794         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. */
795                 is_valid = 1;
796                 break;
797         default:
798                 if (200 <= code && code <= 299) {
799                         is_valid = ari_validate_live_recording(
800                                 response->message);
801                 } else {
802                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/record\n", code);
803                         is_valid = 0;
804                 }
805         }
806
807         if (!is_valid) {
808                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/record\n");
809                 stasis_http_response_error(response, 500,
810                         "Internal Server Error", "Response validation failed");
811         }
812 #endif /* AST_DEVMODE */
813 }
814 /*!
815  * \brief Parameter parsing callback for /channels/{channelId}/variable.
816  * \param get_params GET parameters in the HTTP request.
817  * \param path_vars Path variables extracted from the request.
818  * \param headers HTTP headers.
819  * \param[out] response Response to the HTTP request.
820  */
821 static void stasis_http_get_channel_var_cb(
822         struct ast_variable *get_params, struct ast_variable *path_vars,
823         struct ast_variable *headers, struct stasis_http_response *response)
824 {
825 #if defined(AST_DEVMODE)
826         int is_valid;
827         int code;
828 #endif /* AST_DEVMODE */
829
830         struct ast_get_channel_var_args args = {};
831         struct ast_variable *i;
832
833         for (i = get_params; i; i = i->next) {
834                 if (strcmp(i->name, "variable") == 0) {
835                         args.variable = (i->value);
836                 } else
837                 {}
838         }
839         for (i = path_vars; i; i = i->next) {
840                 if (strcmp(i->name, "channelId") == 0) {
841                         args.channel_id = (i->value);
842                 } else
843                 {}
844         }
845         stasis_http_get_channel_var(headers, &args, response);
846 #if defined(AST_DEVMODE)
847         code = response->response_code;
848
849         switch (code) {
850         case 500: /* Internal server error */
851         case 404: /* Channel not found */
852         case 409: /* Channel not in a Stasis application */
853                 is_valid = 1;
854                 break;
855         default:
856                 if (200 <= code && code <= 299) {
857                         is_valid = ari_validate_variable(
858                                 response->message);
859                 } else {
860                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/variable\n", code);
861                         is_valid = 0;
862                 }
863         }
864
865         if (!is_valid) {
866                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/variable\n");
867                 stasis_http_response_error(response, 500,
868                         "Internal Server Error", "Response validation failed");
869         }
870 #endif /* AST_DEVMODE */
871 }
872 /*!
873  * \brief Parameter parsing callback for /channels/{channelId}/variable.
874  * \param get_params GET parameters in the HTTP request.
875  * \param path_vars Path variables extracted from the request.
876  * \param headers HTTP headers.
877  * \param[out] response Response to the HTTP request.
878  */
879 static void stasis_http_set_channel_var_cb(
880         struct ast_variable *get_params, struct ast_variable *path_vars,
881         struct ast_variable *headers, struct stasis_http_response *response)
882 {
883 #if defined(AST_DEVMODE)
884         int is_valid;
885         int code;
886 #endif /* AST_DEVMODE */
887
888         struct ast_set_channel_var_args args = {};
889         struct ast_variable *i;
890
891         for (i = get_params; i; i = i->next) {
892                 if (strcmp(i->name, "variable") == 0) {
893                         args.variable = (i->value);
894                 } else
895                 if (strcmp(i->name, "value") == 0) {
896                         args.value = (i->value);
897                 } else
898                 {}
899         }
900         for (i = path_vars; i; i = i->next) {
901                 if (strcmp(i->name, "channelId") == 0) {
902                         args.channel_id = (i->value);
903                 } else
904                 {}
905         }
906         stasis_http_set_channel_var(headers, &args, response);
907 #if defined(AST_DEVMODE)
908         code = response->response_code;
909
910         switch (code) {
911         case 500: /* Internal server error */
912         case 404: /* Channel not found */
913         case 409: /* Channel not in a Stasis application */
914                 is_valid = 1;
915                 break;
916         default:
917                 if (200 <= code && code <= 299) {
918                         is_valid = ari_validate_void(
919                                 response->message);
920                 } else {
921                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/variable\n", code);
922                         is_valid = 0;
923                 }
924         }
925
926         if (!is_valid) {
927                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/variable\n");
928                 stasis_http_response_error(response, 500,
929                         "Internal Server Error", "Response validation failed");
930         }
931 #endif /* AST_DEVMODE */
932 }
933
934 /*! \brief REST handler for /api-docs/channels.{format} */
935 static struct stasis_rest_handlers channels_channelId_dial = {
936         .path_segment = "dial",
937         .callbacks = {
938                 [AST_HTTP_POST] = stasis_http_dial_cb,
939         },
940         .num_children = 0,
941         .children = {  }
942 };
943 /*! \brief REST handler for /api-docs/channels.{format} */
944 static struct stasis_rest_handlers channels_channelId_continue = {
945         .path_segment = "continue",
946         .callbacks = {
947                 [AST_HTTP_POST] = stasis_http_continue_in_dialplan_cb,
948         },
949         .num_children = 0,
950         .children = {  }
951 };
952 /*! \brief REST handler for /api-docs/channels.{format} */
953 static struct stasis_rest_handlers channels_channelId_answer = {
954         .path_segment = "answer",
955         .callbacks = {
956                 [AST_HTTP_POST] = stasis_http_answer_channel_cb,
957         },
958         .num_children = 0,
959         .children = {  }
960 };
961 /*! \brief REST handler for /api-docs/channels.{format} */
962 static struct stasis_rest_handlers channels_channelId_mute = {
963         .path_segment = "mute",
964         .callbacks = {
965                 [AST_HTTP_POST] = stasis_http_mute_channel_cb,
966         },
967         .num_children = 0,
968         .children = {  }
969 };
970 /*! \brief REST handler for /api-docs/channels.{format} */
971 static struct stasis_rest_handlers channels_channelId_unmute = {
972         .path_segment = "unmute",
973         .callbacks = {
974                 [AST_HTTP_POST] = stasis_http_unmute_channel_cb,
975         },
976         .num_children = 0,
977         .children = {  }
978 };
979 /*! \brief REST handler for /api-docs/channels.{format} */
980 static struct stasis_rest_handlers channels_channelId_hold = {
981         .path_segment = "hold",
982         .callbacks = {
983                 [AST_HTTP_POST] = stasis_http_hold_channel_cb,
984         },
985         .num_children = 0,
986         .children = {  }
987 };
988 /*! \brief REST handler for /api-docs/channels.{format} */
989 static struct stasis_rest_handlers channels_channelId_unhold = {
990         .path_segment = "unhold",
991         .callbacks = {
992                 [AST_HTTP_POST] = stasis_http_unhold_channel_cb,
993         },
994         .num_children = 0,
995         .children = {  }
996 };
997 /*! \brief REST handler for /api-docs/channels.{format} */
998 static struct stasis_rest_handlers channels_channelId_play = {
999         .path_segment = "play",
1000         .callbacks = {
1001                 [AST_HTTP_POST] = stasis_http_play_on_channel_cb,
1002         },
1003         .num_children = 0,
1004         .children = {  }
1005 };
1006 /*! \brief REST handler for /api-docs/channels.{format} */
1007 static struct stasis_rest_handlers channels_channelId_record = {
1008         .path_segment = "record",
1009         .callbacks = {
1010                 [AST_HTTP_POST] = stasis_http_record_channel_cb,
1011         },
1012         .num_children = 0,
1013         .children = {  }
1014 };
1015 /*! \brief REST handler for /api-docs/channels.{format} */
1016 static struct stasis_rest_handlers channels_channelId_variable = {
1017         .path_segment = "variable",
1018         .callbacks = {
1019                 [AST_HTTP_GET] = stasis_http_get_channel_var_cb,
1020                 [AST_HTTP_POST] = stasis_http_set_channel_var_cb,
1021         },
1022         .num_children = 0,
1023         .children = {  }
1024 };
1025 /*! \brief REST handler for /api-docs/channels.{format} */
1026 static struct stasis_rest_handlers channels_channelId = {
1027         .path_segment = "channelId",
1028         .is_wildcard = 1,
1029         .callbacks = {
1030                 [AST_HTTP_GET] = stasis_http_get_channel_cb,
1031                 [AST_HTTP_DELETE] = stasis_http_delete_channel_cb,
1032         },
1033         .num_children = 10,
1034         .children = { &channels_channelId_dial,&channels_channelId_continue,&channels_channelId_answer,&channels_channelId_mute,&channels_channelId_unmute,&channels_channelId_hold,&channels_channelId_unhold,&channels_channelId_play,&channels_channelId_record,&channels_channelId_variable, }
1035 };
1036 /*! \brief REST handler for /api-docs/channels.{format} */
1037 static struct stasis_rest_handlers channels = {
1038         .path_segment = "channels",
1039         .callbacks = {
1040                 [AST_HTTP_GET] = stasis_http_get_channels_cb,
1041                 [AST_HTTP_POST] = stasis_http_originate_cb,
1042         },
1043         .num_children = 1,
1044         .children = { &channels_channelId, }
1045 };
1046
1047 static int load_module(void)
1048 {
1049         int res = 0;
1050         stasis_app_ref();
1051         res |= stasis_http_add_handler(&channels);
1052         return res;
1053 }
1054
1055 static int unload_module(void)
1056 {
1057         stasis_http_remove_handler(&channels);
1058         stasis_app_unref();
1059         return 0;
1060 }
1061
1062 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "RESTful API module - Channel resources",
1063         .load = load_module,
1064         .unload = unload_module,
1065         .nonoptreq = "res_stasis_http,res_stasis",
1066         );