ARI: MOH start and stop for a channel
[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}/mohstart.
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_moh_start_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_moh_start_channel_args args = {};
687         struct ast_variable *i;
688
689         for (i = get_params; i; i = i->next) {
690                 if (strcmp(i->name, "mohClass") == 0) {
691                         args.moh_class = (i->value);
692                 } else
693                 {}
694         }
695         for (i = path_vars; i; i = i->next) {
696                 if (strcmp(i->name, "channelId") == 0) {
697                         args.channel_id = (i->value);
698                 } else
699                 {}
700         }
701         stasis_http_moh_start_channel(headers, &args, response);
702 #if defined(AST_DEVMODE)
703         code = response->response_code;
704
705         switch (code) {
706         case 500: /* Internal server error */
707         case 404: /* Channel not found */
708         case 409: /* Channel not in a Stasis application */
709                 is_valid = 1;
710                 break;
711         default:
712                 if (200 <= code && code <= 299) {
713                         is_valid = ari_validate_void(
714                                 response->message);
715                 } else {
716                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/mohstart\n", code);
717                         is_valid = 0;
718                 }
719         }
720
721         if (!is_valid) {
722                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/mohstart\n");
723                 stasis_http_response_error(response, 500,
724                         "Internal Server Error", "Response validation failed");
725         }
726 #endif /* AST_DEVMODE */
727 }
728 /*!
729  * \brief Parameter parsing callback for /channels/{channelId}/mohstop.
730  * \param get_params GET parameters in the HTTP request.
731  * \param path_vars Path variables extracted from the request.
732  * \param headers HTTP headers.
733  * \param[out] response Response to the HTTP request.
734  */
735 static void stasis_http_moh_stop_channel_cb(
736         struct ast_variable *get_params, struct ast_variable *path_vars,
737         struct ast_variable *headers, struct stasis_http_response *response)
738 {
739 #if defined(AST_DEVMODE)
740         int is_valid;
741         int code;
742 #endif /* AST_DEVMODE */
743
744         struct ast_moh_stop_channel_args args = {};
745         struct ast_variable *i;
746
747         for (i = path_vars; i; i = i->next) {
748                 if (strcmp(i->name, "channelId") == 0) {
749                         args.channel_id = (i->value);
750                 } else
751                 {}
752         }
753         stasis_http_moh_stop_channel(headers, &args, response);
754 #if defined(AST_DEVMODE)
755         code = response->response_code;
756
757         switch (code) {
758         case 500: /* Internal server error */
759         case 404: /* Channel not found */
760         case 409: /* Channel not in a Stasis application */
761                 is_valid = 1;
762                 break;
763         default:
764                 if (200 <= code && code <= 299) {
765                         is_valid = ari_validate_void(
766                                 response->message);
767                 } else {
768                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/mohstop\n", code);
769                         is_valid = 0;
770                 }
771         }
772
773         if (!is_valid) {
774                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/mohstop\n");
775                 stasis_http_response_error(response, 500,
776                         "Internal Server Error", "Response validation failed");
777         }
778 #endif /* AST_DEVMODE */
779 }
780 /*!
781  * \brief Parameter parsing callback for /channels/{channelId}/play.
782  * \param get_params GET parameters in the HTTP request.
783  * \param path_vars Path variables extracted from the request.
784  * \param headers HTTP headers.
785  * \param[out] response Response to the HTTP request.
786  */
787 static void stasis_http_play_on_channel_cb(
788         struct ast_variable *get_params, struct ast_variable *path_vars,
789         struct ast_variable *headers, struct stasis_http_response *response)
790 {
791 #if defined(AST_DEVMODE)
792         int is_valid;
793         int code;
794 #endif /* AST_DEVMODE */
795
796         struct ast_play_on_channel_args args = {};
797         struct ast_variable *i;
798
799         for (i = get_params; i; i = i->next) {
800                 if (strcmp(i->name, "media") == 0) {
801                         args.media = (i->value);
802                 } else
803                 if (strcmp(i->name, "lang") == 0) {
804                         args.lang = (i->value);
805                 } else
806                 if (strcmp(i->name, "offsetms") == 0) {
807                         args.offsetms = atoi(i->value);
808                 } else
809                 if (strcmp(i->name, "skipms") == 0) {
810                         args.skipms = atoi(i->value);
811                 } else
812                 {}
813         }
814         for (i = path_vars; i; i = i->next) {
815                 if (strcmp(i->name, "channelId") == 0) {
816                         args.channel_id = (i->value);
817                 } else
818                 {}
819         }
820         stasis_http_play_on_channel(headers, &args, response);
821 #if defined(AST_DEVMODE)
822         code = response->response_code;
823
824         switch (code) {
825         case 500: /* Internal server error */
826         case 404: /* Channel not found */
827         case 409: /* Channel not in a Stasis application */
828                 is_valid = 1;
829                 break;
830         default:
831                 if (200 <= code && code <= 299) {
832                         is_valid = ari_validate_playback(
833                                 response->message);
834                 } else {
835                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/play\n", code);
836                         is_valid = 0;
837                 }
838         }
839
840         if (!is_valid) {
841                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/play\n");
842                 stasis_http_response_error(response, 500,
843                         "Internal Server Error", "Response validation failed");
844         }
845 #endif /* AST_DEVMODE */
846 }
847 /*!
848  * \brief Parameter parsing callback for /channels/{channelId}/record.
849  * \param get_params GET parameters in the HTTP request.
850  * \param path_vars Path variables extracted from the request.
851  * \param headers HTTP headers.
852  * \param[out] response Response to the HTTP request.
853  */
854 static void stasis_http_record_channel_cb(
855         struct ast_variable *get_params, struct ast_variable *path_vars,
856         struct ast_variable *headers, struct stasis_http_response *response)
857 {
858 #if defined(AST_DEVMODE)
859         int is_valid;
860         int code;
861 #endif /* AST_DEVMODE */
862
863         struct ast_record_channel_args args = {};
864         struct ast_variable *i;
865
866         for (i = get_params; i; i = i->next) {
867                 if (strcmp(i->name, "name") == 0) {
868                         args.name = (i->value);
869                 } else
870                 if (strcmp(i->name, "format") == 0) {
871                         args.format = (i->value);
872                 } else
873                 if (strcmp(i->name, "maxDurationSeconds") == 0) {
874                         args.max_duration_seconds = atoi(i->value);
875                 } else
876                 if (strcmp(i->name, "maxSilenceSeconds") == 0) {
877                         args.max_silence_seconds = atoi(i->value);
878                 } else
879                 if (strcmp(i->name, "ifExists") == 0) {
880                         args.if_exists = (i->value);
881                 } else
882                 if (strcmp(i->name, "beep") == 0) {
883                         args.beep = ast_true(i->value);
884                 } else
885                 if (strcmp(i->name, "terminateOn") == 0) {
886                         args.terminate_on = (i->value);
887                 } else
888                 {}
889         }
890         for (i = path_vars; i; i = i->next) {
891                 if (strcmp(i->name, "channelId") == 0) {
892                         args.channel_id = (i->value);
893                 } else
894                 {}
895         }
896         stasis_http_record_channel(headers, &args, response);
897 #if defined(AST_DEVMODE)
898         code = response->response_code;
899
900         switch (code) {
901         case 500: /* Internal server error */
902         case 400: /* Invalid parameters */
903         case 404: /* Channel not found */
904         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. */
905                 is_valid = 1;
906                 break;
907         default:
908                 if (200 <= code && code <= 299) {
909                         is_valid = ari_validate_live_recording(
910                                 response->message);
911                 } else {
912                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/record\n", code);
913                         is_valid = 0;
914                 }
915         }
916
917         if (!is_valid) {
918                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/record\n");
919                 stasis_http_response_error(response, 500,
920                         "Internal Server Error", "Response validation failed");
921         }
922 #endif /* AST_DEVMODE */
923 }
924 /*!
925  * \brief Parameter parsing callback for /channels/{channelId}/variable.
926  * \param get_params GET parameters in the HTTP request.
927  * \param path_vars Path variables extracted from the request.
928  * \param headers HTTP headers.
929  * \param[out] response Response to the HTTP request.
930  */
931 static void stasis_http_get_channel_var_cb(
932         struct ast_variable *get_params, struct ast_variable *path_vars,
933         struct ast_variable *headers, struct stasis_http_response *response)
934 {
935 #if defined(AST_DEVMODE)
936         int is_valid;
937         int code;
938 #endif /* AST_DEVMODE */
939
940         struct ast_get_channel_var_args args = {};
941         struct ast_variable *i;
942
943         for (i = get_params; i; i = i->next) {
944                 if (strcmp(i->name, "variable") == 0) {
945                         args.variable = (i->value);
946                 } else
947                 {}
948         }
949         for (i = path_vars; i; i = i->next) {
950                 if (strcmp(i->name, "channelId") == 0) {
951                         args.channel_id = (i->value);
952                 } else
953                 {}
954         }
955         stasis_http_get_channel_var(headers, &args, response);
956 #if defined(AST_DEVMODE)
957         code = response->response_code;
958
959         switch (code) {
960         case 500: /* Internal server error */
961         case 404: /* Channel not found */
962         case 409: /* Channel not in a Stasis application */
963                 is_valid = 1;
964                 break;
965         default:
966                 if (200 <= code && code <= 299) {
967                         is_valid = ari_validate_variable(
968                                 response->message);
969                 } else {
970                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/variable\n", code);
971                         is_valid = 0;
972                 }
973         }
974
975         if (!is_valid) {
976                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/variable\n");
977                 stasis_http_response_error(response, 500,
978                         "Internal Server Error", "Response validation failed");
979         }
980 #endif /* AST_DEVMODE */
981 }
982 /*!
983  * \brief Parameter parsing callback for /channels/{channelId}/variable.
984  * \param get_params GET parameters in the HTTP request.
985  * \param path_vars Path variables extracted from the request.
986  * \param headers HTTP headers.
987  * \param[out] response Response to the HTTP request.
988  */
989 static void stasis_http_set_channel_var_cb(
990         struct ast_variable *get_params, struct ast_variable *path_vars,
991         struct ast_variable *headers, struct stasis_http_response *response)
992 {
993 #if defined(AST_DEVMODE)
994         int is_valid;
995         int code;
996 #endif /* AST_DEVMODE */
997
998         struct ast_set_channel_var_args args = {};
999         struct ast_variable *i;
1000
1001         for (i = get_params; i; i = i->next) {
1002                 if (strcmp(i->name, "variable") == 0) {
1003                         args.variable = (i->value);
1004                 } else
1005                 if (strcmp(i->name, "value") == 0) {
1006                         args.value = (i->value);
1007                 } else
1008                 {}
1009         }
1010         for (i = path_vars; i; i = i->next) {
1011                 if (strcmp(i->name, "channelId") == 0) {
1012                         args.channel_id = (i->value);
1013                 } else
1014                 {}
1015         }
1016         stasis_http_set_channel_var(headers, &args, response);
1017 #if defined(AST_DEVMODE)
1018         code = response->response_code;
1019
1020         switch (code) {
1021         case 500: /* Internal server error */
1022         case 404: /* Channel not found */
1023         case 409: /* Channel not in a Stasis application */
1024                 is_valid = 1;
1025                 break;
1026         default:
1027                 if (200 <= code && code <= 299) {
1028                         is_valid = ari_validate_void(
1029                                 response->message);
1030                 } else {
1031                         ast_log(LOG_ERROR, "Invalid error response %d for /channels/{channelId}/variable\n", code);
1032                         is_valid = 0;
1033                 }
1034         }
1035
1036         if (!is_valid) {
1037                 ast_log(LOG_ERROR, "Response validation failed for /channels/{channelId}/variable\n");
1038                 stasis_http_response_error(response, 500,
1039                         "Internal Server Error", "Response validation failed");
1040         }
1041 #endif /* AST_DEVMODE */
1042 }
1043
1044 /*! \brief REST handler for /api-docs/channels.{format} */
1045 static struct stasis_rest_handlers channels_channelId_dial = {
1046         .path_segment = "dial",
1047         .callbacks = {
1048                 [AST_HTTP_POST] = stasis_http_dial_cb,
1049         },
1050         .num_children = 0,
1051         .children = {  }
1052 };
1053 /*! \brief REST handler for /api-docs/channels.{format} */
1054 static struct stasis_rest_handlers channels_channelId_continue = {
1055         .path_segment = "continue",
1056         .callbacks = {
1057                 [AST_HTTP_POST] = stasis_http_continue_in_dialplan_cb,
1058         },
1059         .num_children = 0,
1060         .children = {  }
1061 };
1062 /*! \brief REST handler for /api-docs/channels.{format} */
1063 static struct stasis_rest_handlers channels_channelId_answer = {
1064         .path_segment = "answer",
1065         .callbacks = {
1066                 [AST_HTTP_POST] = stasis_http_answer_channel_cb,
1067         },
1068         .num_children = 0,
1069         .children = {  }
1070 };
1071 /*! \brief REST handler for /api-docs/channels.{format} */
1072 static struct stasis_rest_handlers channels_channelId_mute = {
1073         .path_segment = "mute",
1074         .callbacks = {
1075                 [AST_HTTP_POST] = stasis_http_mute_channel_cb,
1076         },
1077         .num_children = 0,
1078         .children = {  }
1079 };
1080 /*! \brief REST handler for /api-docs/channels.{format} */
1081 static struct stasis_rest_handlers channels_channelId_unmute = {
1082         .path_segment = "unmute",
1083         .callbacks = {
1084                 [AST_HTTP_POST] = stasis_http_unmute_channel_cb,
1085         },
1086         .num_children = 0,
1087         .children = {  }
1088 };
1089 /*! \brief REST handler for /api-docs/channels.{format} */
1090 static struct stasis_rest_handlers channels_channelId_hold = {
1091         .path_segment = "hold",
1092         .callbacks = {
1093                 [AST_HTTP_POST] = stasis_http_hold_channel_cb,
1094         },
1095         .num_children = 0,
1096         .children = {  }
1097 };
1098 /*! \brief REST handler for /api-docs/channels.{format} */
1099 static struct stasis_rest_handlers channels_channelId_unhold = {
1100         .path_segment = "unhold",
1101         .callbacks = {
1102                 [AST_HTTP_POST] = stasis_http_unhold_channel_cb,
1103         },
1104         .num_children = 0,
1105         .children = {  }
1106 };
1107 /*! \brief REST handler for /api-docs/channels.{format} */
1108 static struct stasis_rest_handlers channels_channelId_mohstart = {
1109         .path_segment = "mohstart",
1110         .callbacks = {
1111                 [AST_HTTP_POST] = stasis_http_moh_start_channel_cb,
1112         },
1113         .num_children = 0,
1114         .children = {  }
1115 };
1116 /*! \brief REST handler for /api-docs/channels.{format} */
1117 static struct stasis_rest_handlers channels_channelId_mohstop = {
1118         .path_segment = "mohstop",
1119         .callbacks = {
1120                 [AST_HTTP_POST] = stasis_http_moh_stop_channel_cb,
1121         },
1122         .num_children = 0,
1123         .children = {  }
1124 };
1125 /*! \brief REST handler for /api-docs/channels.{format} */
1126 static struct stasis_rest_handlers channels_channelId_play = {
1127         .path_segment = "play",
1128         .callbacks = {
1129                 [AST_HTTP_POST] = stasis_http_play_on_channel_cb,
1130         },
1131         .num_children = 0,
1132         .children = {  }
1133 };
1134 /*! \brief REST handler for /api-docs/channels.{format} */
1135 static struct stasis_rest_handlers channels_channelId_record = {
1136         .path_segment = "record",
1137         .callbacks = {
1138                 [AST_HTTP_POST] = stasis_http_record_channel_cb,
1139         },
1140         .num_children = 0,
1141         .children = {  }
1142 };
1143 /*! \brief REST handler for /api-docs/channels.{format} */
1144 static struct stasis_rest_handlers channels_channelId_variable = {
1145         .path_segment = "variable",
1146         .callbacks = {
1147                 [AST_HTTP_GET] = stasis_http_get_channel_var_cb,
1148                 [AST_HTTP_POST] = stasis_http_set_channel_var_cb,
1149         },
1150         .num_children = 0,
1151         .children = {  }
1152 };
1153 /*! \brief REST handler for /api-docs/channels.{format} */
1154 static struct stasis_rest_handlers channels_channelId = {
1155         .path_segment = "channelId",
1156         .is_wildcard = 1,
1157         .callbacks = {
1158                 [AST_HTTP_GET] = stasis_http_get_channel_cb,
1159                 [AST_HTTP_DELETE] = stasis_http_delete_channel_cb,
1160         },
1161         .num_children = 12,
1162         .children = { &channels_channelId_dial,&channels_channelId_continue,&channels_channelId_answer,&channels_channelId_mute,&channels_channelId_unmute,&channels_channelId_hold,&channels_channelId_unhold,&channels_channelId_mohstart,&channels_channelId_mohstop,&channels_channelId_play,&channels_channelId_record,&channels_channelId_variable, }
1163 };
1164 /*! \brief REST handler for /api-docs/channels.{format} */
1165 static struct stasis_rest_handlers channels = {
1166         .path_segment = "channels",
1167         .callbacks = {
1168                 [AST_HTTP_GET] = stasis_http_get_channels_cb,
1169                 [AST_HTTP_POST] = stasis_http_originate_cb,
1170         },
1171         .num_children = 1,
1172         .children = { &channels_channelId, }
1173 };
1174
1175 static int load_module(void)
1176 {
1177         int res = 0;
1178         stasis_app_ref();
1179         res |= stasis_http_add_handler(&channels);
1180         return res;
1181 }
1182
1183 static int unload_module(void)
1184 {
1185         stasis_http_remove_handler(&channels);
1186         stasis_app_unref();
1187         return 0;
1188 }
1189
1190 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "RESTful API module - Channel resources",
1191         .load = load_module,
1192         .unload = unload_module,
1193         .nonoptreq = "res_stasis_http,res_stasis",
1194         );