ARI recordings: Issue HTTP failures for recording requests with file conflicts
[asterisk/asterisk.git] / res / res_ari_bridges.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 Bridge 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_bridges.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 /bridges.
56  * \param get_params GET parameters in the HTTP request.
57  * \param path_vars Path variables extracted from the request.
58  * \param headers HTTP headers.
59  * \param[out] response Response to the HTTP request.
60  */
61 static void ast_ari_get_bridges_cb(
62         struct ast_variable *get_params, struct ast_variable *path_vars,
63         struct ast_variable *headers, struct ast_ari_response *response)
64 {
65         struct ast_get_bridges_args args = {};
66 #if defined(AST_DEVMODE)
67         int is_valid;
68         int code;
69 #endif /* AST_DEVMODE */
70
71         ast_ari_get_bridges(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_bridge_fn());
87                 } else {
88                         ast_log(LOG_ERROR, "Invalid error response %d for /bridges\n", code);
89                         is_valid = 0;
90                 }
91         }
92
93         if (!is_valid) {
94                 ast_log(LOG_ERROR, "Response validation failed for /bridges\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 /bridges.
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_new_bridge_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_new_bridge_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, "type") == 0) {
123                         args.type = (i->value);
124                 } else
125                 {}
126         }
127         ast_ari_new_bridge(headers, &args, response);
128 #if defined(AST_DEVMODE)
129         code = response->response_code;
130
131         switch (code) {
132         case 0: /* Implementation is still a stub, or the code wasn't set */
133                 is_valid = response->message == NULL;
134                 break;
135         case 500: /* Internal Server Error */
136         case 501: /* Not Implemented */
137                 is_valid = 1;
138                 break;
139         default:
140                 if (200 <= code && code <= 299) {
141                         is_valid = ast_ari_validate_bridge(
142                                 response->message);
143                 } else {
144                         ast_log(LOG_ERROR, "Invalid error response %d for /bridges\n", code);
145                         is_valid = 0;
146                 }
147         }
148
149         if (!is_valid) {
150                 ast_log(LOG_ERROR, "Response validation failed for /bridges\n");
151                 ast_ari_response_error(response, 500,
152                         "Internal Server Error", "Response validation failed");
153         }
154 #endif /* AST_DEVMODE */
155
156 fin: __attribute__((unused))
157         return;
158 }
159 /*!
160  * \brief Parameter parsing callback for /bridges/{bridgeId}.
161  * \param get_params GET parameters in the HTTP request.
162  * \param path_vars Path variables extracted from the request.
163  * \param headers HTTP headers.
164  * \param[out] response Response to the HTTP request.
165  */
166 static void ast_ari_get_bridge_cb(
167         struct ast_variable *get_params, struct ast_variable *path_vars,
168         struct ast_variable *headers, struct ast_ari_response *response)
169 {
170         struct ast_get_bridge_args args = {};
171         struct ast_variable *i;
172 #if defined(AST_DEVMODE)
173         int is_valid;
174         int code;
175 #endif /* AST_DEVMODE */
176
177         for (i = path_vars; i; i = i->next) {
178                 if (strcmp(i->name, "bridgeId") == 0) {
179                         args.bridge_id = (i->value);
180                 } else
181                 {}
182         }
183         ast_ari_get_bridge(headers, &args, response);
184 #if defined(AST_DEVMODE)
185         code = response->response_code;
186
187         switch (code) {
188         case 0: /* Implementation is still a stub, or the code wasn't set */
189                 is_valid = response->message == NULL;
190                 break;
191         case 500: /* Internal Server Error */
192         case 501: /* Not Implemented */
193         case 404: /* Bridge not found */
194                 is_valid = 1;
195                 break;
196         default:
197                 if (200 <= code && code <= 299) {
198                         is_valid = ast_ari_validate_bridge(
199                                 response->message);
200                 } else {
201                         ast_log(LOG_ERROR, "Invalid error response %d for /bridges/{bridgeId}\n", code);
202                         is_valid = 0;
203                 }
204         }
205
206         if (!is_valid) {
207                 ast_log(LOG_ERROR, "Response validation failed for /bridges/{bridgeId}\n");
208                 ast_ari_response_error(response, 500,
209                         "Internal Server Error", "Response validation failed");
210         }
211 #endif /* AST_DEVMODE */
212
213 fin: __attribute__((unused))
214         return;
215 }
216 /*!
217  * \brief Parameter parsing callback for /bridges/{bridgeId}.
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 ast_ari_delete_bridge_cb(
224         struct ast_variable *get_params, struct ast_variable *path_vars,
225         struct ast_variable *headers, struct ast_ari_response *response)
226 {
227         struct ast_delete_bridge_args args = {};
228         struct ast_variable *i;
229 #if defined(AST_DEVMODE)
230         int is_valid;
231         int code;
232 #endif /* AST_DEVMODE */
233
234         for (i = path_vars; i; i = i->next) {
235                 if (strcmp(i->name, "bridgeId") == 0) {
236                         args.bridge_id = (i->value);
237                 } else
238                 {}
239         }
240         ast_ari_delete_bridge(headers, &args, response);
241 #if defined(AST_DEVMODE)
242         code = response->response_code;
243
244         switch (code) {
245         case 0: /* Implementation is still a stub, or the code wasn't set */
246                 is_valid = response->message == NULL;
247                 break;
248         case 500: /* Internal Server Error */
249         case 501: /* Not Implemented */
250         case 404: /* Bridge not found */
251                 is_valid = 1;
252                 break;
253         default:
254                 if (200 <= code && code <= 299) {
255                         is_valid = ast_ari_validate_void(
256                                 response->message);
257                 } else {
258                         ast_log(LOG_ERROR, "Invalid error response %d for /bridges/{bridgeId}\n", code);
259                         is_valid = 0;
260                 }
261         }
262
263         if (!is_valid) {
264                 ast_log(LOG_ERROR, "Response validation failed for /bridges/{bridgeId}\n");
265                 ast_ari_response_error(response, 500,
266                         "Internal Server Error", "Response validation failed");
267         }
268 #endif /* AST_DEVMODE */
269
270 fin: __attribute__((unused))
271         return;
272 }
273 /*!
274  * \brief Parameter parsing callback for /bridges/{bridgeId}/addChannel.
275  * \param get_params GET parameters in the HTTP request.
276  * \param path_vars Path variables extracted from the request.
277  * \param headers HTTP headers.
278  * \param[out] response Response to the HTTP request.
279  */
280 static void ast_ari_add_channel_to_bridge_cb(
281         struct ast_variable *get_params, struct ast_variable *path_vars,
282         struct ast_variable *headers, struct ast_ari_response *response)
283 {
284         struct ast_add_channel_to_bridge_args args = {};
285         struct ast_variable *i;
286 #if defined(AST_DEVMODE)
287         int is_valid;
288         int code;
289 #endif /* AST_DEVMODE */
290
291         for (i = get_params; i; i = i->next) {
292                 if (strcmp(i->name, "channel") == 0) {
293                         /* Parse comma separated list */
294                         char *vals[MAX_VALS];
295                         size_t j;
296
297                         args.channel_parse = ast_strdup(i->value);
298                         if (!args.channel_parse) {
299                                 ast_ari_response_alloc_failed(response);
300                                 goto fin;
301                         }
302
303                         if (strlen(args.channel_parse) == 0) {
304                                 /* ast_app_separate_args can't handle "" */
305                                 args.channel_count = 1;
306                                 vals[0] = args.channel_parse;
307                         } else {
308                                 args.channel_count = ast_app_separate_args(
309                                         args.channel_parse, ',', vals,
310                                         ARRAY_LEN(vals));
311                         }
312
313                         if (args.channel_count == 0) {
314                                 ast_ari_response_alloc_failed(response);
315                                 goto fin;
316                         }
317
318                         if (args.channel_count >= MAX_VALS) {
319                                 ast_ari_response_error(response, 400,
320                                         "Bad Request",
321                                         "Too many values for channel");
322                                 goto fin;
323                         }
324
325                         args.channel = ast_malloc(sizeof(*args.channel) * args.channel_count);
326                         if (!args.channel) {
327                                 ast_ari_response_alloc_failed(response);
328                                 goto fin;
329                         }
330
331                         for (j = 0; j < args.channel_count; ++j) {
332                                 args.channel[j] = (vals[j]);
333                         }
334                 } else
335                 if (strcmp(i->name, "role") == 0) {
336                         args.role = (i->value);
337                 } else
338                 {}
339         }
340         for (i = path_vars; i; i = i->next) {
341                 if (strcmp(i->name, "bridgeId") == 0) {
342                         args.bridge_id = (i->value);
343                 } else
344                 {}
345         }
346         ast_ari_add_channel_to_bridge(headers, &args, response);
347 #if defined(AST_DEVMODE)
348         code = response->response_code;
349
350         switch (code) {
351         case 0: /* Implementation is still a stub, or the code wasn't set */
352                 is_valid = response->message == NULL;
353                 break;
354         case 500: /* Internal Server Error */
355         case 501: /* Not Implemented */
356         case 400: /* Channel not found */
357         case 404: /* Bridge not found */
358         case 409: /* Bridge not in Stasis application */
359         case 422: /* Channel not in Stasis application */
360                 is_valid = 1;
361                 break;
362         default:
363                 if (200 <= code && code <= 299) {
364                         is_valid = ast_ari_validate_void(
365                                 response->message);
366                 } else {
367                         ast_log(LOG_ERROR, "Invalid error response %d for /bridges/{bridgeId}/addChannel\n", code);
368                         is_valid = 0;
369                 }
370         }
371
372         if (!is_valid) {
373                 ast_log(LOG_ERROR, "Response validation failed for /bridges/{bridgeId}/addChannel\n");
374                 ast_ari_response_error(response, 500,
375                         "Internal Server Error", "Response validation failed");
376         }
377 #endif /* AST_DEVMODE */
378
379 fin: __attribute__((unused))
380         ast_free(args.channel_parse);
381         ast_free(args.channel);
382         return;
383 }
384 /*!
385  * \brief Parameter parsing callback for /bridges/{bridgeId}/removeChannel.
386  * \param get_params GET parameters in the HTTP request.
387  * \param path_vars Path variables extracted from the request.
388  * \param headers HTTP headers.
389  * \param[out] response Response to the HTTP request.
390  */
391 static void ast_ari_remove_channel_from_bridge_cb(
392         struct ast_variable *get_params, struct ast_variable *path_vars,
393         struct ast_variable *headers, struct ast_ari_response *response)
394 {
395         struct ast_remove_channel_from_bridge_args args = {};
396         struct ast_variable *i;
397 #if defined(AST_DEVMODE)
398         int is_valid;
399         int code;
400 #endif /* AST_DEVMODE */
401
402         for (i = get_params; i; i = i->next) {
403                 if (strcmp(i->name, "channel") == 0) {
404                         /* Parse comma separated list */
405                         char *vals[MAX_VALS];
406                         size_t j;
407
408                         args.channel_parse = ast_strdup(i->value);
409                         if (!args.channel_parse) {
410                                 ast_ari_response_alloc_failed(response);
411                                 goto fin;
412                         }
413
414                         if (strlen(args.channel_parse) == 0) {
415                                 /* ast_app_separate_args can't handle "" */
416                                 args.channel_count = 1;
417                                 vals[0] = args.channel_parse;
418                         } else {
419                                 args.channel_count = ast_app_separate_args(
420                                         args.channel_parse, ',', vals,
421                                         ARRAY_LEN(vals));
422                         }
423
424                         if (args.channel_count == 0) {
425                                 ast_ari_response_alloc_failed(response);
426                                 goto fin;
427                         }
428
429                         if (args.channel_count >= MAX_VALS) {
430                                 ast_ari_response_error(response, 400,
431                                         "Bad Request",
432                                         "Too many values for channel");
433                                 goto fin;
434                         }
435
436                         args.channel = ast_malloc(sizeof(*args.channel) * args.channel_count);
437                         if (!args.channel) {
438                                 ast_ari_response_alloc_failed(response);
439                                 goto fin;
440                         }
441
442                         for (j = 0; j < args.channel_count; ++j) {
443                                 args.channel[j] = (vals[j]);
444                         }
445                 } else
446                 {}
447         }
448         for (i = path_vars; i; i = i->next) {
449                 if (strcmp(i->name, "bridgeId") == 0) {
450                         args.bridge_id = (i->value);
451                 } else
452                 {}
453         }
454         ast_ari_remove_channel_from_bridge(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 400: /* Channel not found */
465         case 404: /* Bridge not found */
466         case 409: /* Bridge not in Stasis application */
467         case 422: /* Channel not in this bridge */
468                 is_valid = 1;
469                 break;
470         default:
471                 if (200 <= code && code <= 299) {
472                         is_valid = ast_ari_validate_void(
473                                 response->message);
474                 } else {
475                         ast_log(LOG_ERROR, "Invalid error response %d for /bridges/{bridgeId}/removeChannel\n", code);
476                         is_valid = 0;
477                 }
478         }
479
480         if (!is_valid) {
481                 ast_log(LOG_ERROR, "Response validation failed for /bridges/{bridgeId}/removeChannel\n");
482                 ast_ari_response_error(response, 500,
483                         "Internal Server Error", "Response validation failed");
484         }
485 #endif /* AST_DEVMODE */
486
487 fin: __attribute__((unused))
488         ast_free(args.channel_parse);
489         ast_free(args.channel);
490         return;
491 }
492 /*!
493  * \brief Parameter parsing callback for /bridges/{bridgeId}/moh.
494  * \param get_params GET parameters in the HTTP request.
495  * \param path_vars Path variables extracted from the request.
496  * \param headers HTTP headers.
497  * \param[out] response Response to the HTTP request.
498  */
499 static void ast_ari_moh_start_bridge_cb(
500         struct ast_variable *get_params, struct ast_variable *path_vars,
501         struct ast_variable *headers, struct ast_ari_response *response)
502 {
503         struct ast_moh_start_bridge_args args = {};
504         struct ast_variable *i;
505 #if defined(AST_DEVMODE)
506         int is_valid;
507         int code;
508 #endif /* AST_DEVMODE */
509
510         for (i = get_params; i; i = i->next) {
511                 if (strcmp(i->name, "mohClass") == 0) {
512                         args.moh_class = (i->value);
513                 } else
514                 {}
515         }
516         for (i = path_vars; i; i = i->next) {
517                 if (strcmp(i->name, "bridgeId") == 0) {
518                         args.bridge_id = (i->value);
519                 } else
520                 {}
521         }
522         ast_ari_moh_start_bridge(headers, &args, response);
523 #if defined(AST_DEVMODE)
524         code = response->response_code;
525
526         switch (code) {
527         case 0: /* Implementation is still a stub, or the code wasn't set */
528                 is_valid = response->message == NULL;
529                 break;
530         case 500: /* Internal Server Error */
531         case 501: /* Not Implemented */
532         case 404: /* Bridge not found */
533         case 409: /* Bridge not in Stasis application */
534                 is_valid = 1;
535                 break;
536         default:
537                 if (200 <= code && code <= 299) {
538                         is_valid = ast_ari_validate_void(
539                                 response->message);
540                 } else {
541                         ast_log(LOG_ERROR, "Invalid error response %d for /bridges/{bridgeId}/moh\n", code);
542                         is_valid = 0;
543                 }
544         }
545
546         if (!is_valid) {
547                 ast_log(LOG_ERROR, "Response validation failed for /bridges/{bridgeId}/moh\n");
548                 ast_ari_response_error(response, 500,
549                         "Internal Server Error", "Response validation failed");
550         }
551 #endif /* AST_DEVMODE */
552
553 fin: __attribute__((unused))
554         return;
555 }
556 /*!
557  * \brief Parameter parsing callback for /bridges/{bridgeId}/moh.
558  * \param get_params GET parameters in the HTTP request.
559  * \param path_vars Path variables extracted from the request.
560  * \param headers HTTP headers.
561  * \param[out] response Response to the HTTP request.
562  */
563 static void ast_ari_moh_stop_bridge_cb(
564         struct ast_variable *get_params, struct ast_variable *path_vars,
565         struct ast_variable *headers, struct ast_ari_response *response)
566 {
567         struct ast_moh_stop_bridge_args args = {};
568         struct ast_variable *i;
569 #if defined(AST_DEVMODE)
570         int is_valid;
571         int code;
572 #endif /* AST_DEVMODE */
573
574         for (i = path_vars; i; i = i->next) {
575                 if (strcmp(i->name, "bridgeId") == 0) {
576                         args.bridge_id = (i->value);
577                 } else
578                 {}
579         }
580         ast_ari_moh_stop_bridge(headers, &args, response);
581 #if defined(AST_DEVMODE)
582         code = response->response_code;
583
584         switch (code) {
585         case 0: /* Implementation is still a stub, or the code wasn't set */
586                 is_valid = response->message == NULL;
587                 break;
588         case 500: /* Internal Server Error */
589         case 501: /* Not Implemented */
590         case 404: /* Bridge not found */
591         case 409: /* Bridge not in Stasis application */
592                 is_valid = 1;
593                 break;
594         default:
595                 if (200 <= code && code <= 299) {
596                         is_valid = ast_ari_validate_void(
597                                 response->message);
598                 } else {
599                         ast_log(LOG_ERROR, "Invalid error response %d for /bridges/{bridgeId}/moh\n", code);
600                         is_valid = 0;
601                 }
602         }
603
604         if (!is_valid) {
605                 ast_log(LOG_ERROR, "Response validation failed for /bridges/{bridgeId}/moh\n");
606                 ast_ari_response_error(response, 500,
607                         "Internal Server Error", "Response validation failed");
608         }
609 #endif /* AST_DEVMODE */
610
611 fin: __attribute__((unused))
612         return;
613 }
614 /*!
615  * \brief Parameter parsing callback for /bridges/{bridgeId}/play.
616  * \param get_params GET parameters in the HTTP request.
617  * \param path_vars Path variables extracted from the request.
618  * \param headers HTTP headers.
619  * \param[out] response Response to the HTTP request.
620  */
621 static void ast_ari_play_on_bridge_cb(
622         struct ast_variable *get_params, struct ast_variable *path_vars,
623         struct ast_variable *headers, struct ast_ari_response *response)
624 {
625         struct ast_play_on_bridge_args args = {};
626         struct ast_variable *i;
627 #if defined(AST_DEVMODE)
628         int is_valid;
629         int code;
630 #endif /* AST_DEVMODE */
631
632         for (i = get_params; i; i = i->next) {
633                 if (strcmp(i->name, "media") == 0) {
634                         args.media = (i->value);
635                 } else
636                 if (strcmp(i->name, "lang") == 0) {
637                         args.lang = (i->value);
638                 } else
639                 if (strcmp(i->name, "offsetms") == 0) {
640                         args.offsetms = atoi(i->value);
641                 } else
642                 if (strcmp(i->name, "skipms") == 0) {
643                         args.skipms = atoi(i->value);
644                 } else
645                 {}
646         }
647         for (i = path_vars; i; i = i->next) {
648                 if (strcmp(i->name, "bridgeId") == 0) {
649                         args.bridge_id = (i->value);
650                 } else
651                 {}
652         }
653         ast_ari_play_on_bridge(headers, &args, response);
654 #if defined(AST_DEVMODE)
655         code = response->response_code;
656
657         switch (code) {
658         case 0: /* Implementation is still a stub, or the code wasn't set */
659                 is_valid = response->message == NULL;
660                 break;
661         case 500: /* Internal Server Error */
662         case 501: /* Not Implemented */
663         case 404: /* Bridge not found */
664         case 409: /* Bridge not in a Stasis application */
665                 is_valid = 1;
666                 break;
667         default:
668                 if (200 <= code && code <= 299) {
669                         is_valid = ast_ari_validate_playback(
670                                 response->message);
671                 } else {
672                         ast_log(LOG_ERROR, "Invalid error response %d for /bridges/{bridgeId}/play\n", code);
673                         is_valid = 0;
674                 }
675         }
676
677         if (!is_valid) {
678                 ast_log(LOG_ERROR, "Response validation failed for /bridges/{bridgeId}/play\n");
679                 ast_ari_response_error(response, 500,
680                         "Internal Server Error", "Response validation failed");
681         }
682 #endif /* AST_DEVMODE */
683
684 fin: __attribute__((unused))
685         return;
686 }
687 /*!
688  * \brief Parameter parsing callback for /bridges/{bridgeId}/record.
689  * \param get_params GET parameters in the HTTP request.
690  * \param path_vars Path variables extracted from the request.
691  * \param headers HTTP headers.
692  * \param[out] response Response to the HTTP request.
693  */
694 static void ast_ari_record_bridge_cb(
695         struct ast_variable *get_params, struct ast_variable *path_vars,
696         struct ast_variable *headers, struct ast_ari_response *response)
697 {
698         struct ast_record_bridge_args args = {};
699         struct ast_variable *i;
700 #if defined(AST_DEVMODE)
701         int is_valid;
702         int code;
703 #endif /* AST_DEVMODE */
704
705         for (i = get_params; i; i = i->next) {
706                 if (strcmp(i->name, "name") == 0) {
707                         args.name = (i->value);
708                 } else
709                 if (strcmp(i->name, "format") == 0) {
710                         args.format = (i->value);
711                 } else
712                 if (strcmp(i->name, "maxDurationSeconds") == 0) {
713                         args.max_duration_seconds = atoi(i->value);
714                 } else
715                 if (strcmp(i->name, "maxSilenceSeconds") == 0) {
716                         args.max_silence_seconds = atoi(i->value);
717                 } else
718                 if (strcmp(i->name, "ifExists") == 0) {
719                         args.if_exists = (i->value);
720                 } else
721                 if (strcmp(i->name, "beep") == 0) {
722                         args.beep = ast_true(i->value);
723                 } else
724                 if (strcmp(i->name, "terminateOn") == 0) {
725                         args.terminate_on = (i->value);
726                 } else
727                 {}
728         }
729         for (i = path_vars; i; i = i->next) {
730                 if (strcmp(i->name, "bridgeId") == 0) {
731                         args.bridge_id = (i->value);
732                 } else
733                 {}
734         }
735         ast_ari_record_bridge(headers, &args, response);
736 #if defined(AST_DEVMODE)
737         code = response->response_code;
738
739         switch (code) {
740         case 0: /* Implementation is still a stub, or the code wasn't set */
741                 is_valid = response->message == NULL;
742                 break;
743         case 500: /* Internal Server Error */
744         case 501: /* Not Implemented */
745         case 400: /* Invalid parameters */
746         case 404: /* Bridge not found */
747         case 409: /* Bridge is not in a Stasis application; A recording with the same name already exists on the system and can not be overwritten because it is in progress or ifExists=fail */
748                 is_valid = 1;
749                 break;
750         default:
751                 if (200 <= code && code <= 299) {
752                         is_valid = ast_ari_validate_live_recording(
753                                 response->message);
754                 } else {
755                         ast_log(LOG_ERROR, "Invalid error response %d for /bridges/{bridgeId}/record\n", code);
756                         is_valid = 0;
757                 }
758         }
759
760         if (!is_valid) {
761                 ast_log(LOG_ERROR, "Response validation failed for /bridges/{bridgeId}/record\n");
762                 ast_ari_response_error(response, 500,
763                         "Internal Server Error", "Response validation failed");
764         }
765 #endif /* AST_DEVMODE */
766
767 fin: __attribute__((unused))
768         return;
769 }
770
771 /*! \brief REST handler for /api-docs/bridges.{format} */
772 static struct stasis_rest_handlers bridges_bridgeId_addChannel = {
773         .path_segment = "addChannel",
774         .callbacks = {
775                 [AST_HTTP_POST] = ast_ari_add_channel_to_bridge_cb,
776         },
777         .num_children = 0,
778         .children = {  }
779 };
780 /*! \brief REST handler for /api-docs/bridges.{format} */
781 static struct stasis_rest_handlers bridges_bridgeId_removeChannel = {
782         .path_segment = "removeChannel",
783         .callbacks = {
784                 [AST_HTTP_POST] = ast_ari_remove_channel_from_bridge_cb,
785         },
786         .num_children = 0,
787         .children = {  }
788 };
789 /*! \brief REST handler for /api-docs/bridges.{format} */
790 static struct stasis_rest_handlers bridges_bridgeId_moh = {
791         .path_segment = "moh",
792         .callbacks = {
793                 [AST_HTTP_POST] = ast_ari_moh_start_bridge_cb,
794                 [AST_HTTP_DELETE] = ast_ari_moh_stop_bridge_cb,
795         },
796         .num_children = 0,
797         .children = {  }
798 };
799 /*! \brief REST handler for /api-docs/bridges.{format} */
800 static struct stasis_rest_handlers bridges_bridgeId_play = {
801         .path_segment = "play",
802         .callbacks = {
803                 [AST_HTTP_POST] = ast_ari_play_on_bridge_cb,
804         },
805         .num_children = 0,
806         .children = {  }
807 };
808 /*! \brief REST handler for /api-docs/bridges.{format} */
809 static struct stasis_rest_handlers bridges_bridgeId_record = {
810         .path_segment = "record",
811         .callbacks = {
812                 [AST_HTTP_POST] = ast_ari_record_bridge_cb,
813         },
814         .num_children = 0,
815         .children = {  }
816 };
817 /*! \brief REST handler for /api-docs/bridges.{format} */
818 static struct stasis_rest_handlers bridges_bridgeId = {
819         .path_segment = "bridgeId",
820         .is_wildcard = 1,
821         .callbacks = {
822                 [AST_HTTP_GET] = ast_ari_get_bridge_cb,
823                 [AST_HTTP_DELETE] = ast_ari_delete_bridge_cb,
824         },
825         .num_children = 5,
826         .children = { &bridges_bridgeId_addChannel,&bridges_bridgeId_removeChannel,&bridges_bridgeId_moh,&bridges_bridgeId_play,&bridges_bridgeId_record, }
827 };
828 /*! \brief REST handler for /api-docs/bridges.{format} */
829 static struct stasis_rest_handlers bridges = {
830         .path_segment = "bridges",
831         .callbacks = {
832                 [AST_HTTP_GET] = ast_ari_get_bridges_cb,
833                 [AST_HTTP_POST] = ast_ari_new_bridge_cb,
834         },
835         .num_children = 1,
836         .children = { &bridges_bridgeId, }
837 };
838
839 static int load_module(void)
840 {
841         int res = 0;
842         stasis_app_ref();
843         res |= ast_ari_add_handler(&bridges);
844         return res;
845 }
846
847 static int unload_module(void)
848 {
849         ast_ari_remove_handler(&bridges);
850         stasis_app_unref();
851         return 0;
852 }
853
854 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "RESTful API module - Bridge resources",
855         .load = load_module,
856         .unload = unload_module,
857         .nonoptreq = "res_ari,res_stasis",
858         );