f2ee8c03add101d95423789606b4435bbf40b055
[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/module.h"
45 #include "asterisk/stasis_app.h"
46 #include "ari/resource_bridges.h"
47 #if defined(AST_DEVMODE)
48 #include "ari/ari_model_validators.h"
49 #endif
50
51 /*!
52  * \brief Parameter parsing callback for /bridges.
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 ast_ari_get_bridges_cb(
59         struct ast_variable *get_params, struct ast_variable *path_vars,
60         struct ast_variable *headers, struct ast_ari_response *response)
61 {
62 #if defined(AST_DEVMODE)
63         int is_valid;
64         int code;
65 #endif /* AST_DEVMODE */
66
67         struct ast_get_bridges_args args = {};
68         ast_ari_get_bridges(headers, &args, response);
69 #if defined(AST_DEVMODE)
70         code = response->response_code;
71
72         switch (code) {
73         case 0: /* Implementation is still a stub, or the code wasn't set */
74                 is_valid = response->message == NULL;
75                 break;
76         case 500: /* Internal Server Error */
77         case 501: /* Not Implemented */
78                 is_valid = 1;
79                 break;
80         default:
81                 if (200 <= code && code <= 299) {
82                         is_valid = ast_ari_validate_list(response->message,
83                                 ast_ari_validate_bridge_fn());
84                 } else {
85                         ast_log(LOG_ERROR, "Invalid error response %d for /bridges\n", code);
86                         is_valid = 0;
87                 }
88         }
89
90         if (!is_valid) {
91                 ast_log(LOG_ERROR, "Response validation failed for /bridges\n");
92                 ast_ari_response_error(response, 500,
93                         "Internal Server Error", "Response validation failed");
94         }
95 #endif /* AST_DEVMODE */
96 }
97 /*!
98  * \brief Parameter parsing callback for /bridges.
99  * \param get_params GET parameters in the HTTP request.
100  * \param path_vars Path variables extracted from the request.
101  * \param headers HTTP headers.
102  * \param[out] response Response to the HTTP request.
103  */
104 static void ast_ari_new_bridge_cb(
105         struct ast_variable *get_params, struct ast_variable *path_vars,
106         struct ast_variable *headers, struct ast_ari_response *response)
107 {
108 #if defined(AST_DEVMODE)
109         int is_valid;
110         int code;
111 #endif /* AST_DEVMODE */
112
113         struct ast_new_bridge_args args = {};
114         struct ast_variable *i;
115
116         for (i = get_params; i; i = i->next) {
117                 if (strcmp(i->name, "type") == 0) {
118                         args.type = (i->value);
119                 } else
120                 {}
121         }
122         ast_ari_new_bridge(headers, &args, response);
123 #if defined(AST_DEVMODE)
124         code = response->response_code;
125
126         switch (code) {
127         case 0: /* Implementation is still a stub, or the code wasn't set */
128                 is_valid = response->message == NULL;
129                 break;
130         case 500: /* Internal Server Error */
131         case 501: /* Not Implemented */
132                 is_valid = 1;
133                 break;
134         default:
135                 if (200 <= code && code <= 299) {
136                         is_valid = ast_ari_validate_bridge(
137                                 response->message);
138                 } else {
139                         ast_log(LOG_ERROR, "Invalid error response %d for /bridges\n", code);
140                         is_valid = 0;
141                 }
142         }
143
144         if (!is_valid) {
145                 ast_log(LOG_ERROR, "Response validation failed for /bridges\n");
146                 ast_ari_response_error(response, 500,
147                         "Internal Server Error", "Response validation failed");
148         }
149 #endif /* AST_DEVMODE */
150 }
151 /*!
152  * \brief Parameter parsing callback for /bridges/{bridgeId}.
153  * \param get_params GET parameters in the HTTP request.
154  * \param path_vars Path variables extracted from the request.
155  * \param headers HTTP headers.
156  * \param[out] response Response to the HTTP request.
157  */
158 static void ast_ari_get_bridge_cb(
159         struct ast_variable *get_params, struct ast_variable *path_vars,
160         struct ast_variable *headers, struct ast_ari_response *response)
161 {
162 #if defined(AST_DEVMODE)
163         int is_valid;
164         int code;
165 #endif /* AST_DEVMODE */
166
167         struct ast_get_bridge_args args = {};
168         struct ast_variable *i;
169
170         for (i = path_vars; i; i = i->next) {
171                 if (strcmp(i->name, "bridgeId") == 0) {
172                         args.bridge_id = (i->value);
173                 } else
174                 {}
175         }
176         ast_ari_get_bridge(headers, &args, response);
177 #if defined(AST_DEVMODE)
178         code = response->response_code;
179
180         switch (code) {
181         case 0: /* Implementation is still a stub, or the code wasn't set */
182                 is_valid = response->message == NULL;
183                 break;
184         case 500: /* Internal Server Error */
185         case 501: /* Not Implemented */
186         case 404: /* Bridge not found */
187                 is_valid = 1;
188                 break;
189         default:
190                 if (200 <= code && code <= 299) {
191                         is_valid = ast_ari_validate_bridge(
192                                 response->message);
193                 } else {
194                         ast_log(LOG_ERROR, "Invalid error response %d for /bridges/{bridgeId}\n", code);
195                         is_valid = 0;
196                 }
197         }
198
199         if (!is_valid) {
200                 ast_log(LOG_ERROR, "Response validation failed for /bridges/{bridgeId}\n");
201                 ast_ari_response_error(response, 500,
202                         "Internal Server Error", "Response validation failed");
203         }
204 #endif /* AST_DEVMODE */
205 }
206 /*!
207  * \brief Parameter parsing callback for /bridges/{bridgeId}.
208  * \param get_params GET parameters in the HTTP request.
209  * \param path_vars Path variables extracted from the request.
210  * \param headers HTTP headers.
211  * \param[out] response Response to the HTTP request.
212  */
213 static void ast_ari_delete_bridge_cb(
214         struct ast_variable *get_params, struct ast_variable *path_vars,
215         struct ast_variable *headers, struct ast_ari_response *response)
216 {
217 #if defined(AST_DEVMODE)
218         int is_valid;
219         int code;
220 #endif /* AST_DEVMODE */
221
222         struct ast_delete_bridge_args args = {};
223         struct ast_variable *i;
224
225         for (i = path_vars; i; i = i->next) {
226                 if (strcmp(i->name, "bridgeId") == 0) {
227                         args.bridge_id = (i->value);
228                 } else
229                 {}
230         }
231         ast_ari_delete_bridge(headers, &args, response);
232 #if defined(AST_DEVMODE)
233         code = response->response_code;
234
235         switch (code) {
236         case 0: /* Implementation is still a stub, or the code wasn't set */
237                 is_valid = response->message == NULL;
238                 break;
239         case 500: /* Internal Server Error */
240         case 501: /* Not Implemented */
241         case 404: /* Bridge not found */
242                 is_valid = 1;
243                 break;
244         default:
245                 if (200 <= code && code <= 299) {
246                         is_valid = ast_ari_validate_void(
247                                 response->message);
248                 } else {
249                         ast_log(LOG_ERROR, "Invalid error response %d for /bridges/{bridgeId}\n", code);
250                         is_valid = 0;
251                 }
252         }
253
254         if (!is_valid) {
255                 ast_log(LOG_ERROR, "Response validation failed for /bridges/{bridgeId}\n");
256                 ast_ari_response_error(response, 500,
257                         "Internal Server Error", "Response validation failed");
258         }
259 #endif /* AST_DEVMODE */
260 }
261 /*!
262  * \brief Parameter parsing callback for /bridges/{bridgeId}/addChannel.
263  * \param get_params GET parameters in the HTTP request.
264  * \param path_vars Path variables extracted from the request.
265  * \param headers HTTP headers.
266  * \param[out] response Response to the HTTP request.
267  */
268 static void ast_ari_add_channel_to_bridge_cb(
269         struct ast_variable *get_params, struct ast_variable *path_vars,
270         struct ast_variable *headers, struct ast_ari_response *response)
271 {
272 #if defined(AST_DEVMODE)
273         int is_valid;
274         int code;
275 #endif /* AST_DEVMODE */
276
277         struct ast_add_channel_to_bridge_args args = {};
278         struct ast_variable *i;
279
280         for (i = get_params; i; i = i->next) {
281                 if (strcmp(i->name, "channel") == 0) {
282                         args.channel = (i->value);
283                 } else
284                 {}
285         }
286         for (i = path_vars; i; i = i->next) {
287                 if (strcmp(i->name, "bridgeId") == 0) {
288                         args.bridge_id = (i->value);
289                 } else
290                 {}
291         }
292         ast_ari_add_channel_to_bridge(headers, &args, response);
293 #if defined(AST_DEVMODE)
294         code = response->response_code;
295
296         switch (code) {
297         case 0: /* Implementation is still a stub, or the code wasn't set */
298                 is_valid = response->message == NULL;
299                 break;
300         case 500: /* Internal Server Error */
301         case 501: /* Not Implemented */
302         case 404: /* Bridge not found */
303         case 409: /* Bridge not in Stasis application */
304         case 422: /* Channel not found, or not in Stasis application */
305                 is_valid = 1;
306                 break;
307         default:
308                 if (200 <= code && code <= 299) {
309                         is_valid = ast_ari_validate_void(
310                                 response->message);
311                 } else {
312                         ast_log(LOG_ERROR, "Invalid error response %d for /bridges/{bridgeId}/addChannel\n", code);
313                         is_valid = 0;
314                 }
315         }
316
317         if (!is_valid) {
318                 ast_log(LOG_ERROR, "Response validation failed for /bridges/{bridgeId}/addChannel\n");
319                 ast_ari_response_error(response, 500,
320                         "Internal Server Error", "Response validation failed");
321         }
322 #endif /* AST_DEVMODE */
323 }
324 /*!
325  * \brief Parameter parsing callback for /bridges/{bridgeId}/removeChannel.
326  * \param get_params GET parameters in the HTTP request.
327  * \param path_vars Path variables extracted from the request.
328  * \param headers HTTP headers.
329  * \param[out] response Response to the HTTP request.
330  */
331 static void ast_ari_remove_channel_from_bridge_cb(
332         struct ast_variable *get_params, struct ast_variable *path_vars,
333         struct ast_variable *headers, struct ast_ari_response *response)
334 {
335 #if defined(AST_DEVMODE)
336         int is_valid;
337         int code;
338 #endif /* AST_DEVMODE */
339
340         struct ast_remove_channel_from_bridge_args args = {};
341         struct ast_variable *i;
342
343         for (i = get_params; i; i = i->next) {
344                 if (strcmp(i->name, "channel") == 0) {
345                         args.channel = (i->value);
346                 } else
347                 {}
348         }
349         for (i = path_vars; i; i = i->next) {
350                 if (strcmp(i->name, "bridgeId") == 0) {
351                         args.bridge_id = (i->value);
352                 } else
353                 {}
354         }
355         ast_ari_remove_channel_from_bridge(headers, &args, response);
356 #if defined(AST_DEVMODE)
357         code = response->response_code;
358
359         switch (code) {
360         case 0: /* Implementation is still a stub, or the code wasn't set */
361                 is_valid = response->message == NULL;
362                 break;
363         case 500: /* Internal Server Error */
364         case 501: /* Not Implemented */
365                 is_valid = 1;
366                 break;
367         default:
368                 if (200 <= code && code <= 299) {
369                         is_valid = ast_ari_validate_void(
370                                 response->message);
371                 } else {
372                         ast_log(LOG_ERROR, "Invalid error response %d for /bridges/{bridgeId}/removeChannel\n", code);
373                         is_valid = 0;
374                 }
375         }
376
377         if (!is_valid) {
378                 ast_log(LOG_ERROR, "Response validation failed for /bridges/{bridgeId}/removeChannel\n");
379                 ast_ari_response_error(response, 500,
380                         "Internal Server Error", "Response validation failed");
381         }
382 #endif /* AST_DEVMODE */
383 }
384 /*!
385  * \brief Parameter parsing callback for /bridges/{bridgeId}/play.
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_play_on_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 #if defined(AST_DEVMODE)
396         int is_valid;
397         int code;
398 #endif /* AST_DEVMODE */
399
400         struct ast_play_on_bridge_args args = {};
401         struct ast_variable *i;
402
403         for (i = get_params; i; i = i->next) {
404                 if (strcmp(i->name, "media") == 0) {
405                         args.media = (i->value);
406                 } else
407                 if (strcmp(i->name, "lang") == 0) {
408                         args.lang = (i->value);
409                 } else
410                 if (strcmp(i->name, "offsetms") == 0) {
411                         args.offsetms = atoi(i->value);
412                 } else
413                 if (strcmp(i->name, "skipms") == 0) {
414                         args.skipms = atoi(i->value);
415                 } else
416                 {}
417         }
418         for (i = path_vars; i; i = i->next) {
419                 if (strcmp(i->name, "bridgeId") == 0) {
420                         args.bridge_id = (i->value);
421                 } else
422                 {}
423         }
424         ast_ari_play_on_bridge(headers, &args, response);
425 #if defined(AST_DEVMODE)
426         code = response->response_code;
427
428         switch (code) {
429         case 0: /* Implementation is still a stub, or the code wasn't set */
430                 is_valid = response->message == NULL;
431                 break;
432         case 500: /* Internal Server Error */
433         case 501: /* Not Implemented */
434         case 404: /* Bridge not found */
435         case 409: /* Bridge not in a Stasis application */
436                 is_valid = 1;
437                 break;
438         default:
439                 if (200 <= code && code <= 299) {
440                         is_valid = ast_ari_validate_playback(
441                                 response->message);
442                 } else {
443                         ast_log(LOG_ERROR, "Invalid error response %d for /bridges/{bridgeId}/play\n", code);
444                         is_valid = 0;
445                 }
446         }
447
448         if (!is_valid) {
449                 ast_log(LOG_ERROR, "Response validation failed for /bridges/{bridgeId}/play\n");
450                 ast_ari_response_error(response, 500,
451                         "Internal Server Error", "Response validation failed");
452         }
453 #endif /* AST_DEVMODE */
454 }
455 /*!
456  * \brief Parameter parsing callback for /bridges/{bridgeId}/record.
457  * \param get_params GET parameters in the HTTP request.
458  * \param path_vars Path variables extracted from the request.
459  * \param headers HTTP headers.
460  * \param[out] response Response to the HTTP request.
461  */
462 static void ast_ari_record_bridge_cb(
463         struct ast_variable *get_params, struct ast_variable *path_vars,
464         struct ast_variable *headers, struct ast_ari_response *response)
465 {
466 #if defined(AST_DEVMODE)
467         int is_valid;
468         int code;
469 #endif /* AST_DEVMODE */
470
471         struct ast_record_bridge_args args = {};
472         struct ast_variable *i;
473
474         for (i = get_params; i; i = i->next) {
475                 if (strcmp(i->name, "name") == 0) {
476                         args.name = (i->value);
477                 } else
478                 if (strcmp(i->name, "format") == 0) {
479                         args.format = (i->value);
480                 } else
481                 if (strcmp(i->name, "maxDurationSeconds") == 0) {
482                         args.max_duration_seconds = atoi(i->value);
483                 } else
484                 if (strcmp(i->name, "maxSilenceSeconds") == 0) {
485                         args.max_silence_seconds = atoi(i->value);
486                 } else
487                 if (strcmp(i->name, "ifExists") == 0) {
488                         args.if_exists = (i->value);
489                 } else
490                 if (strcmp(i->name, "beep") == 0) {
491                         args.beep = ast_true(i->value);
492                 } else
493                 if (strcmp(i->name, "terminateOn") == 0) {
494                         args.terminate_on = (i->value);
495                 } else
496                 {}
497         }
498         for (i = path_vars; i; i = i->next) {
499                 if (strcmp(i->name, "bridgeId") == 0) {
500                         args.bridge_id = (i->value);
501                 } else
502                 {}
503         }
504         ast_ari_record_bridge(headers, &args, response);
505 #if defined(AST_DEVMODE)
506         code = response->response_code;
507
508         switch (code) {
509         case 0: /* Implementation is still a stub, or the code wasn't set */
510                 is_valid = response->message == NULL;
511                 break;
512         case 500: /* Internal Server Error */
513         case 501: /* Not Implemented */
514                 is_valid = 1;
515                 break;
516         default:
517                 if (200 <= code && code <= 299) {
518                         is_valid = ast_ari_validate_live_recording(
519                                 response->message);
520                 } else {
521                         ast_log(LOG_ERROR, "Invalid error response %d for /bridges/{bridgeId}/record\n", code);
522                         is_valid = 0;
523                 }
524         }
525
526         if (!is_valid) {
527                 ast_log(LOG_ERROR, "Response validation failed for /bridges/{bridgeId}/record\n");
528                 ast_ari_response_error(response, 500,
529                         "Internal Server Error", "Response validation failed");
530         }
531 #endif /* AST_DEVMODE */
532 }
533
534 /*! \brief REST handler for /api-docs/bridges.{format} */
535 static struct stasis_rest_handlers bridges_bridgeId_addChannel = {
536         .path_segment = "addChannel",
537         .callbacks = {
538                 [AST_HTTP_POST] = ast_ari_add_channel_to_bridge_cb,
539         },
540         .num_children = 0,
541         .children = {  }
542 };
543 /*! \brief REST handler for /api-docs/bridges.{format} */
544 static struct stasis_rest_handlers bridges_bridgeId_removeChannel = {
545         .path_segment = "removeChannel",
546         .callbacks = {
547                 [AST_HTTP_POST] = ast_ari_remove_channel_from_bridge_cb,
548         },
549         .num_children = 0,
550         .children = {  }
551 };
552 /*! \brief REST handler for /api-docs/bridges.{format} */
553 static struct stasis_rest_handlers bridges_bridgeId_play = {
554         .path_segment = "play",
555         .callbacks = {
556                 [AST_HTTP_POST] = ast_ari_play_on_bridge_cb,
557         },
558         .num_children = 0,
559         .children = {  }
560 };
561 /*! \brief REST handler for /api-docs/bridges.{format} */
562 static struct stasis_rest_handlers bridges_bridgeId_record = {
563         .path_segment = "record",
564         .callbacks = {
565                 [AST_HTTP_POST] = ast_ari_record_bridge_cb,
566         },
567         .num_children = 0,
568         .children = {  }
569 };
570 /*! \brief REST handler for /api-docs/bridges.{format} */
571 static struct stasis_rest_handlers bridges_bridgeId = {
572         .path_segment = "bridgeId",
573         .is_wildcard = 1,
574         .callbacks = {
575                 [AST_HTTP_GET] = ast_ari_get_bridge_cb,
576                 [AST_HTTP_DELETE] = ast_ari_delete_bridge_cb,
577         },
578         .num_children = 4,
579         .children = { &bridges_bridgeId_addChannel,&bridges_bridgeId_removeChannel,&bridges_bridgeId_play,&bridges_bridgeId_record, }
580 };
581 /*! \brief REST handler for /api-docs/bridges.{format} */
582 static struct stasis_rest_handlers bridges = {
583         .path_segment = "bridges",
584         .callbacks = {
585                 [AST_HTTP_GET] = ast_ari_get_bridges_cb,
586                 [AST_HTTP_POST] = ast_ari_new_bridge_cb,
587         },
588         .num_children = 1,
589         .children = { &bridges_bridgeId, }
590 };
591
592 static int load_module(void)
593 {
594         int res = 0;
595         stasis_app_ref();
596         res |= ast_ari_add_handler(&bridges);
597         return res;
598 }
599
600 static int unload_module(void)
601 {
602         ast_ari_remove_handler(&bridges);
603         stasis_app_unref();
604         return 0;
605 }
606
607 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "RESTful API module - Bridge resources",
608         .load = load_module,
609         .unload = unload_module,
610         .nonoptreq = "res_ari,res_stasis",
611         );