ARI: Correct error codes for bridge operations
[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                         args.channel_count = ast_app_separate_args(
304                                 args.channel_parse, ',', vals, ARRAY_LEN(vals));
305                         if (args.channel_count == 0) {
306                                 ast_ari_response_alloc_failed(response);
307                                 goto fin;
308                         }
309
310                         if (args.channel_count >= MAX_VALS) {
311                                 ast_ari_response_error(response, 400,
312                                         "Bad Request",
313                                         "Too many values for channel");
314                                 goto fin;
315                         }
316
317                         args.channel = ast_malloc(sizeof(*args.channel) * args.channel_count);
318                         if (!args.channel) {
319                                 ast_ari_response_alloc_failed(response);
320                                 goto fin;
321                         }
322
323                         for (j = 0; j < args.channel_count; ++j) {
324                                 args.channel[j] = (vals[j]);
325                         }
326                 } else
327                 if (strcmp(i->name, "role") == 0) {
328                         args.role = (i->value);
329                 } else
330                 {}
331         }
332         for (i = path_vars; i; i = i->next) {
333                 if (strcmp(i->name, "bridgeId") == 0) {
334                         args.bridge_id = (i->value);
335                 } else
336                 {}
337         }
338         ast_ari_add_channel_to_bridge(headers, &args, response);
339 #if defined(AST_DEVMODE)
340         code = response->response_code;
341
342         switch (code) {
343         case 0: /* Implementation is still a stub, or the code wasn't set */
344                 is_valid = response->message == NULL;
345                 break;
346         case 500: /* Internal Server Error */
347         case 501: /* Not Implemented */
348         case 400: /* Channel not found */
349         case 404: /* Bridge not found */
350         case 409: /* Bridge not in Stasis application */
351         case 422: /* Channel not in Stasis application */
352                 is_valid = 1;
353                 break;
354         default:
355                 if (200 <= code && code <= 299) {
356                         is_valid = ast_ari_validate_void(
357                                 response->message);
358                 } else {
359                         ast_log(LOG_ERROR, "Invalid error response %d for /bridges/{bridgeId}/addChannel\n", code);
360                         is_valid = 0;
361                 }
362         }
363
364         if (!is_valid) {
365                 ast_log(LOG_ERROR, "Response validation failed for /bridges/{bridgeId}/addChannel\n");
366                 ast_ari_response_error(response, 500,
367                         "Internal Server Error", "Response validation failed");
368         }
369 #endif /* AST_DEVMODE */
370
371 fin: __attribute__((unused))
372         ast_free(args.channel_parse);
373         ast_free(args.channel);
374         return;
375 }
376 /*!
377  * \brief Parameter parsing callback for /bridges/{bridgeId}/removeChannel.
378  * \param get_params GET parameters in the HTTP request.
379  * \param path_vars Path variables extracted from the request.
380  * \param headers HTTP headers.
381  * \param[out] response Response to the HTTP request.
382  */
383 static void ast_ari_remove_channel_from_bridge_cb(
384         struct ast_variable *get_params, struct ast_variable *path_vars,
385         struct ast_variable *headers, struct ast_ari_response *response)
386 {
387         struct ast_remove_channel_from_bridge_args args = {};
388         struct ast_variable *i;
389 #if defined(AST_DEVMODE)
390         int is_valid;
391         int code;
392 #endif /* AST_DEVMODE */
393
394         for (i = get_params; i; i = i->next) {
395                 if (strcmp(i->name, "channel") == 0) {
396                         /* Parse comma separated list */
397                         char *vals[MAX_VALS];
398                         size_t j;
399
400                         args.channel_parse = ast_strdup(i->value);
401                         if (!args.channel_parse) {
402                                 ast_ari_response_alloc_failed(response);
403                                 goto fin;
404                         }
405
406                         args.channel_count = ast_app_separate_args(
407                                 args.channel_parse, ',', vals, ARRAY_LEN(vals));
408                         if (args.channel_count == 0) {
409                                 ast_ari_response_alloc_failed(response);
410                                 goto fin;
411                         }
412
413                         if (args.channel_count >= MAX_VALS) {
414                                 ast_ari_response_error(response, 400,
415                                         "Bad Request",
416                                         "Too many values for channel");
417                                 goto fin;
418                         }
419
420                         args.channel = ast_malloc(sizeof(*args.channel) * args.channel_count);
421                         if (!args.channel) {
422                                 ast_ari_response_alloc_failed(response);
423                                 goto fin;
424                         }
425
426                         for (j = 0; j < args.channel_count; ++j) {
427                                 args.channel[j] = (vals[j]);
428                         }
429                 } else
430                 {}
431         }
432         for (i = path_vars; i; i = i->next) {
433                 if (strcmp(i->name, "bridgeId") == 0) {
434                         args.bridge_id = (i->value);
435                 } else
436                 {}
437         }
438         ast_ari_remove_channel_from_bridge(headers, &args, response);
439 #if defined(AST_DEVMODE)
440         code = response->response_code;
441
442         switch (code) {
443         case 0: /* Implementation is still a stub, or the code wasn't set */
444                 is_valid = response->message == NULL;
445                 break;
446         case 500: /* Internal Server Error */
447         case 501: /* Not Implemented */
448         case 400: /* Channel not found */
449         case 404: /* Bridge not found */
450         case 409: /* Bridge not in Stasis application */
451         case 422: /* Channel not in this bridge */
452                 is_valid = 1;
453                 break;
454         default:
455                 if (200 <= code && code <= 299) {
456                         is_valid = ast_ari_validate_void(
457                                 response->message);
458                 } else {
459                         ast_log(LOG_ERROR, "Invalid error response %d for /bridges/{bridgeId}/removeChannel\n", code);
460                         is_valid = 0;
461                 }
462         }
463
464         if (!is_valid) {
465                 ast_log(LOG_ERROR, "Response validation failed for /bridges/{bridgeId}/removeChannel\n");
466                 ast_ari_response_error(response, 500,
467                         "Internal Server Error", "Response validation failed");
468         }
469 #endif /* AST_DEVMODE */
470
471 fin: __attribute__((unused))
472         ast_free(args.channel_parse);
473         ast_free(args.channel);
474         return;
475 }
476 /*!
477  * \brief Parameter parsing callback for /bridges/{bridgeId}/mohStart.
478  * \param get_params GET parameters in the HTTP request.
479  * \param path_vars Path variables extracted from the request.
480  * \param headers HTTP headers.
481  * \param[out] response Response to the HTTP request.
482  */
483 static void ast_ari_moh_start_bridge_cb(
484         struct ast_variable *get_params, struct ast_variable *path_vars,
485         struct ast_variable *headers, struct ast_ari_response *response)
486 {
487         struct ast_moh_start_bridge_args args = {};
488         struct ast_variable *i;
489 #if defined(AST_DEVMODE)
490         int is_valid;
491         int code;
492 #endif /* AST_DEVMODE */
493
494         for (i = get_params; i; i = i->next) {
495                 if (strcmp(i->name, "mohClass") == 0) {
496                         args.moh_class = (i->value);
497                 } else
498                 {}
499         }
500         for (i = path_vars; i; i = i->next) {
501                 if (strcmp(i->name, "bridgeId") == 0) {
502                         args.bridge_id = (i->value);
503                 } else
504                 {}
505         }
506         ast_ari_moh_start_bridge(headers, &args, response);
507 #if defined(AST_DEVMODE)
508         code = response->response_code;
509
510         switch (code) {
511         case 0: /* Implementation is still a stub, or the code wasn't set */
512                 is_valid = response->message == NULL;
513                 break;
514         case 500: /* Internal Server Error */
515         case 501: /* Not Implemented */
516         case 404: /* Bridge not found */
517         case 409: /* Bridge not in Stasis application */
518                 is_valid = 1;
519                 break;
520         default:
521                 if (200 <= code && code <= 299) {
522                         is_valid = ast_ari_validate_void(
523                                 response->message);
524                 } else {
525                         ast_log(LOG_ERROR, "Invalid error response %d for /bridges/{bridgeId}/mohStart\n", code);
526                         is_valid = 0;
527                 }
528         }
529
530         if (!is_valid) {
531                 ast_log(LOG_ERROR, "Response validation failed for /bridges/{bridgeId}/mohStart\n");
532                 ast_ari_response_error(response, 500,
533                         "Internal Server Error", "Response validation failed");
534         }
535 #endif /* AST_DEVMODE */
536
537 fin: __attribute__((unused))
538         return;
539 }
540 /*!
541  * \brief Parameter parsing callback for /bridges/{bridgeId}/mohStop.
542  * \param get_params GET parameters in the HTTP request.
543  * \param path_vars Path variables extracted from the request.
544  * \param headers HTTP headers.
545  * \param[out] response Response to the HTTP request.
546  */
547 static void ast_ari_moh_stop_bridge_cb(
548         struct ast_variable *get_params, struct ast_variable *path_vars,
549         struct ast_variable *headers, struct ast_ari_response *response)
550 {
551         struct ast_moh_stop_bridge_args args = {};
552         struct ast_variable *i;
553 #if defined(AST_DEVMODE)
554         int is_valid;
555         int code;
556 #endif /* AST_DEVMODE */
557
558         for (i = path_vars; i; i = i->next) {
559                 if (strcmp(i->name, "bridgeId") == 0) {
560                         args.bridge_id = (i->value);
561                 } else
562                 {}
563         }
564         ast_ari_moh_stop_bridge(headers, &args, response);
565 #if defined(AST_DEVMODE)
566         code = response->response_code;
567
568         switch (code) {
569         case 0: /* Implementation is still a stub, or the code wasn't set */
570                 is_valid = response->message == NULL;
571                 break;
572         case 500: /* Internal Server Error */
573         case 501: /* Not Implemented */
574         case 404: /* Bridge not found */
575         case 409: /* Bridge not in Stasis application */
576                 is_valid = 1;
577                 break;
578         default:
579                 if (200 <= code && code <= 299) {
580                         is_valid = ast_ari_validate_void(
581                                 response->message);
582                 } else {
583                         ast_log(LOG_ERROR, "Invalid error response %d for /bridges/{bridgeId}/mohStop\n", code);
584                         is_valid = 0;
585                 }
586         }
587
588         if (!is_valid) {
589                 ast_log(LOG_ERROR, "Response validation failed for /bridges/{bridgeId}/mohStop\n");
590                 ast_ari_response_error(response, 500,
591                         "Internal Server Error", "Response validation failed");
592         }
593 #endif /* AST_DEVMODE */
594
595 fin: __attribute__((unused))
596         return;
597 }
598 /*!
599  * \brief Parameter parsing callback for /bridges/{bridgeId}/play.
600  * \param get_params GET parameters in the HTTP request.
601  * \param path_vars Path variables extracted from the request.
602  * \param headers HTTP headers.
603  * \param[out] response Response to the HTTP request.
604  */
605 static void ast_ari_play_on_bridge_cb(
606         struct ast_variable *get_params, struct ast_variable *path_vars,
607         struct ast_variable *headers, struct ast_ari_response *response)
608 {
609         struct ast_play_on_bridge_args args = {};
610         struct ast_variable *i;
611 #if defined(AST_DEVMODE)
612         int is_valid;
613         int code;
614 #endif /* AST_DEVMODE */
615
616         for (i = get_params; i; i = i->next) {
617                 if (strcmp(i->name, "media") == 0) {
618                         args.media = (i->value);
619                 } else
620                 if (strcmp(i->name, "lang") == 0) {
621                         args.lang = (i->value);
622                 } else
623                 if (strcmp(i->name, "offsetms") == 0) {
624                         args.offsetms = atoi(i->value);
625                 } else
626                 if (strcmp(i->name, "skipms") == 0) {
627                         args.skipms = atoi(i->value);
628                 } else
629                 {}
630         }
631         for (i = path_vars; i; i = i->next) {
632                 if (strcmp(i->name, "bridgeId") == 0) {
633                         args.bridge_id = (i->value);
634                 } else
635                 {}
636         }
637         ast_ari_play_on_bridge(headers, &args, response);
638 #if defined(AST_DEVMODE)
639         code = response->response_code;
640
641         switch (code) {
642         case 0: /* Implementation is still a stub, or the code wasn't set */
643                 is_valid = response->message == NULL;
644                 break;
645         case 500: /* Internal Server Error */
646         case 501: /* Not Implemented */
647         case 404: /* Bridge not found */
648         case 409: /* Bridge not in a Stasis application */
649                 is_valid = 1;
650                 break;
651         default:
652                 if (200 <= code && code <= 299) {
653                         is_valid = ast_ari_validate_playback(
654                                 response->message);
655                 } else {
656                         ast_log(LOG_ERROR, "Invalid error response %d for /bridges/{bridgeId}/play\n", code);
657                         is_valid = 0;
658                 }
659         }
660
661         if (!is_valid) {
662                 ast_log(LOG_ERROR, "Response validation failed for /bridges/{bridgeId}/play\n");
663                 ast_ari_response_error(response, 500,
664                         "Internal Server Error", "Response validation failed");
665         }
666 #endif /* AST_DEVMODE */
667
668 fin: __attribute__((unused))
669         return;
670 }
671 /*!
672  * \brief Parameter parsing callback for /bridges/{bridgeId}/record.
673  * \param get_params GET parameters in the HTTP request.
674  * \param path_vars Path variables extracted from the request.
675  * \param headers HTTP headers.
676  * \param[out] response Response to the HTTP request.
677  */
678 static void ast_ari_record_bridge_cb(
679         struct ast_variable *get_params, struct ast_variable *path_vars,
680         struct ast_variable *headers, struct ast_ari_response *response)
681 {
682         struct ast_record_bridge_args args = {};
683         struct ast_variable *i;
684 #if defined(AST_DEVMODE)
685         int is_valid;
686         int code;
687 #endif /* AST_DEVMODE */
688
689         for (i = get_params; i; i = i->next) {
690                 if (strcmp(i->name, "name") == 0) {
691                         args.name = (i->value);
692                 } else
693                 if (strcmp(i->name, "format") == 0) {
694                         args.format = (i->value);
695                 } else
696                 if (strcmp(i->name, "maxDurationSeconds") == 0) {
697                         args.max_duration_seconds = atoi(i->value);
698                 } else
699                 if (strcmp(i->name, "maxSilenceSeconds") == 0) {
700                         args.max_silence_seconds = atoi(i->value);
701                 } else
702                 if (strcmp(i->name, "ifExists") == 0) {
703                         args.if_exists = (i->value);
704                 } else
705                 if (strcmp(i->name, "beep") == 0) {
706                         args.beep = ast_true(i->value);
707                 } else
708                 if (strcmp(i->name, "terminateOn") == 0) {
709                         args.terminate_on = (i->value);
710                 } else
711                 {}
712         }
713         for (i = path_vars; i; i = i->next) {
714                 if (strcmp(i->name, "bridgeId") == 0) {
715                         args.bridge_id = (i->value);
716                 } else
717                 {}
718         }
719         ast_ari_record_bridge(headers, &args, response);
720 #if defined(AST_DEVMODE)
721         code = response->response_code;
722
723         switch (code) {
724         case 0: /* Implementation is still a stub, or the code wasn't set */
725                 is_valid = response->message == NULL;
726                 break;
727         case 500: /* Internal Server Error */
728         case 501: /* Not Implemented */
729                 is_valid = 1;
730                 break;
731         default:
732                 if (200 <= code && code <= 299) {
733                         is_valid = ast_ari_validate_live_recording(
734                                 response->message);
735                 } else {
736                         ast_log(LOG_ERROR, "Invalid error response %d for /bridges/{bridgeId}/record\n", code);
737                         is_valid = 0;
738                 }
739         }
740
741         if (!is_valid) {
742                 ast_log(LOG_ERROR, "Response validation failed for /bridges/{bridgeId}/record\n");
743                 ast_ari_response_error(response, 500,
744                         "Internal Server Error", "Response validation failed");
745         }
746 #endif /* AST_DEVMODE */
747
748 fin: __attribute__((unused))
749         return;
750 }
751
752 /*! \brief REST handler for /api-docs/bridges.{format} */
753 static struct stasis_rest_handlers bridges_bridgeId_addChannel = {
754         .path_segment = "addChannel",
755         .callbacks = {
756                 [AST_HTTP_POST] = ast_ari_add_channel_to_bridge_cb,
757         },
758         .num_children = 0,
759         .children = {  }
760 };
761 /*! \brief REST handler for /api-docs/bridges.{format} */
762 static struct stasis_rest_handlers bridges_bridgeId_removeChannel = {
763         .path_segment = "removeChannel",
764         .callbacks = {
765                 [AST_HTTP_POST] = ast_ari_remove_channel_from_bridge_cb,
766         },
767         .num_children = 0,
768         .children = {  }
769 };
770 /*! \brief REST handler for /api-docs/bridges.{format} */
771 static struct stasis_rest_handlers bridges_bridgeId_mohStart = {
772         .path_segment = "mohStart",
773         .callbacks = {
774                 [AST_HTTP_POST] = ast_ari_moh_start_bridge_cb,
775         },
776         .num_children = 0,
777         .children = {  }
778 };
779 /*! \brief REST handler for /api-docs/bridges.{format} */
780 static struct stasis_rest_handlers bridges_bridgeId_mohStop = {
781         .path_segment = "mohStop",
782         .callbacks = {
783                 [AST_HTTP_POST] = ast_ari_moh_stop_bridge_cb,
784         },
785         .num_children = 0,
786         .children = {  }
787 };
788 /*! \brief REST handler for /api-docs/bridges.{format} */
789 static struct stasis_rest_handlers bridges_bridgeId_play = {
790         .path_segment = "play",
791         .callbacks = {
792                 [AST_HTTP_POST] = ast_ari_play_on_bridge_cb,
793         },
794         .num_children = 0,
795         .children = {  }
796 };
797 /*! \brief REST handler for /api-docs/bridges.{format} */
798 static struct stasis_rest_handlers bridges_bridgeId_record = {
799         .path_segment = "record",
800         .callbacks = {
801                 [AST_HTTP_POST] = ast_ari_record_bridge_cb,
802         },
803         .num_children = 0,
804         .children = {  }
805 };
806 /*! \brief REST handler for /api-docs/bridges.{format} */
807 static struct stasis_rest_handlers bridges_bridgeId = {
808         .path_segment = "bridgeId",
809         .is_wildcard = 1,
810         .callbacks = {
811                 [AST_HTTP_GET] = ast_ari_get_bridge_cb,
812                 [AST_HTTP_DELETE] = ast_ari_delete_bridge_cb,
813         },
814         .num_children = 6,
815         .children = { &bridges_bridgeId_addChannel,&bridges_bridgeId_removeChannel,&bridges_bridgeId_mohStart,&bridges_bridgeId_mohStop,&bridges_bridgeId_play,&bridges_bridgeId_record, }
816 };
817 /*! \brief REST handler for /api-docs/bridges.{format} */
818 static struct stasis_rest_handlers bridges = {
819         .path_segment = "bridges",
820         .callbacks = {
821                 [AST_HTTP_GET] = ast_ari_get_bridges_cb,
822                 [AST_HTTP_POST] = ast_ari_new_bridge_cb,
823         },
824         .num_children = 1,
825         .children = { &bridges_bridgeId, }
826 };
827
828 static int load_module(void)
829 {
830         int res = 0;
831         stasis_app_ref();
832         res |= ast_ari_add_handler(&bridges);
833         return res;
834 }
835
836 static int unload_module(void)
837 {
838         ast_ari_remove_handler(&bridges);
839         stasis_app_unref();
840         return 0;
841 }
842
843 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "RESTful API module - Bridge resources",
844         .load = load_module,
845         .unload = unload_module,
846         .nonoptreq = "res_ari,res_stasis",
847         );