ARI: Add the ability to download the media associated with a stored recording
[asterisk/asterisk.git] / res / res_ari_recordings.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 Recording 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_ari_model</depend>
37         <depend type="module">res_stasis</depend>
38         <support_level>core</support_level>
39  ***/
40
41 #include "asterisk.h"
42
43 ASTERISK_REGISTER_FILE()
44
45 #include "asterisk/app.h"
46 #include "asterisk/module.h"
47 #include "asterisk/stasis_app.h"
48 #include "ari/resource_recordings.h"
49 #if defined(AST_DEVMODE)
50 #include "ari/ari_model_validators.h"
51 #endif
52
53 #define MAX_VALS 128
54
55 /*!
56  * \brief Parameter parsing callback for /recordings/stored.
57  * \param get_params GET parameters in the HTTP request.
58  * \param path_vars Path variables extracted from the request.
59  * \param headers HTTP headers.
60  * \param[out] response Response to the HTTP request.
61  */
62 static void ast_ari_recordings_list_stored_cb(
63         struct ast_tcptls_session_instance *ser,
64         struct ast_variable *get_params, struct ast_variable *path_vars,
65         struct ast_variable *headers, struct ast_ari_response *response)
66 {
67         struct ast_ari_recordings_list_stored_args args = {};
68         RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
69 #if defined(AST_DEVMODE)
70         int is_valid;
71         int code;
72 #endif /* AST_DEVMODE */
73
74         ast_ari_recordings_list_stored(headers, &args, response);
75 #if defined(AST_DEVMODE)
76         code = response->response_code;
77
78         switch (code) {
79         case 0: /* Implementation is still a stub, or the code wasn't set */
80                 is_valid = response->message == NULL;
81                 break;
82         case 500: /* Internal Server Error */
83         case 501: /* Not Implemented */
84                 is_valid = 1;
85                 break;
86         default:
87                 if (200 <= code && code <= 299) {
88                         is_valid = ast_ari_validate_list(response->message,
89                                 ast_ari_validate_stored_recording_fn());
90                 } else {
91                         ast_log(LOG_ERROR, "Invalid error response %d for /recordings/stored\n", code);
92                         is_valid = 0;
93                 }
94         }
95
96         if (!is_valid) {
97                 ast_log(LOG_ERROR, "Response validation failed for /recordings/stored\n");
98                 ast_ari_response_error(response, 500,
99                         "Internal Server Error", "Response validation failed");
100         }
101 #endif /* AST_DEVMODE */
102
103 fin: __attribute__((unused))
104         return;
105 }
106 /*!
107  * \brief Parameter parsing callback for /recordings/stored/{recordingName}.
108  * \param get_params GET parameters in the HTTP request.
109  * \param path_vars Path variables extracted from the request.
110  * \param headers HTTP headers.
111  * \param[out] response Response to the HTTP request.
112  */
113 static void ast_ari_recordings_get_stored_cb(
114         struct ast_tcptls_session_instance *ser,
115         struct ast_variable *get_params, struct ast_variable *path_vars,
116         struct ast_variable *headers, struct ast_ari_response *response)
117 {
118         struct ast_ari_recordings_get_stored_args args = {};
119         struct ast_variable *i;
120         RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
121 #if defined(AST_DEVMODE)
122         int is_valid;
123         int code;
124 #endif /* AST_DEVMODE */
125
126         for (i = path_vars; i; i = i->next) {
127                 if (strcmp(i->name, "recordingName") == 0) {
128                         args.recording_name = (i->value);
129                 } else
130                 {}
131         }
132         ast_ari_recordings_get_stored(headers, &args, response);
133 #if defined(AST_DEVMODE)
134         code = response->response_code;
135
136         switch (code) {
137         case 0: /* Implementation is still a stub, or the code wasn't set */
138                 is_valid = response->message == NULL;
139                 break;
140         case 500: /* Internal Server Error */
141         case 501: /* Not Implemented */
142         case 404: /* Recording not found */
143                 is_valid = 1;
144                 break;
145         default:
146                 if (200 <= code && code <= 299) {
147                         is_valid = ast_ari_validate_stored_recording(
148                                 response->message);
149                 } else {
150                         ast_log(LOG_ERROR, "Invalid error response %d for /recordings/stored/{recordingName}\n", code);
151                         is_valid = 0;
152                 }
153         }
154
155         if (!is_valid) {
156                 ast_log(LOG_ERROR, "Response validation failed for /recordings/stored/{recordingName}\n");
157                 ast_ari_response_error(response, 500,
158                         "Internal Server Error", "Response validation failed");
159         }
160 #endif /* AST_DEVMODE */
161
162 fin: __attribute__((unused))
163         return;
164 }
165 /*!
166  * \brief Parameter parsing callback for /recordings/stored/{recordingName}.
167  * \param get_params GET parameters in the HTTP request.
168  * \param path_vars Path variables extracted from the request.
169  * \param headers HTTP headers.
170  * \param[out] response Response to the HTTP request.
171  */
172 static void ast_ari_recordings_delete_stored_cb(
173         struct ast_tcptls_session_instance *ser,
174         struct ast_variable *get_params, struct ast_variable *path_vars,
175         struct ast_variable *headers, struct ast_ari_response *response)
176 {
177         struct ast_ari_recordings_delete_stored_args args = {};
178         struct ast_variable *i;
179         RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
180 #if defined(AST_DEVMODE)
181         int is_valid;
182         int code;
183 #endif /* AST_DEVMODE */
184
185         for (i = path_vars; i; i = i->next) {
186                 if (strcmp(i->name, "recordingName") == 0) {
187                         args.recording_name = (i->value);
188                 } else
189                 {}
190         }
191         ast_ari_recordings_delete_stored(headers, &args, response);
192 #if defined(AST_DEVMODE)
193         code = response->response_code;
194
195         switch (code) {
196         case 0: /* Implementation is still a stub, or the code wasn't set */
197                 is_valid = response->message == NULL;
198                 break;
199         case 500: /* Internal Server Error */
200         case 501: /* Not Implemented */
201         case 404: /* Recording not found */
202                 is_valid = 1;
203                 break;
204         default:
205                 if (200 <= code && code <= 299) {
206                         is_valid = ast_ari_validate_void(
207                                 response->message);
208                 } else {
209                         ast_log(LOG_ERROR, "Invalid error response %d for /recordings/stored/{recordingName}\n", code);
210                         is_valid = 0;
211                 }
212         }
213
214         if (!is_valid) {
215                 ast_log(LOG_ERROR, "Response validation failed for /recordings/stored/{recordingName}\n");
216                 ast_ari_response_error(response, 500,
217                         "Internal Server Error", "Response validation failed");
218         }
219 #endif /* AST_DEVMODE */
220
221 fin: __attribute__((unused))
222         return;
223 }
224 /*!
225  * \brief Parameter parsing callback for /recordings/stored/{recordingName}/file.
226  * \param get_params GET parameters in the HTTP request.
227  * \param path_vars Path variables extracted from the request.
228  * \param headers HTTP headers.
229  * \param[out] response Response to the HTTP request.
230  */
231 static void ast_ari_recordings_get_stored_file_cb(
232         struct ast_tcptls_session_instance *ser,
233         struct ast_variable *get_params, struct ast_variable *path_vars,
234         struct ast_variable *headers, struct ast_ari_response *response)
235 {
236         struct ast_ari_recordings_get_stored_file_args args = {};
237         struct ast_variable *i;
238         RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
239 #if defined(AST_DEVMODE)
240         int is_valid;
241         int code;
242 #endif /* AST_DEVMODE */
243
244         for (i = path_vars; i; i = i->next) {
245                 if (strcmp(i->name, "recordingName") == 0) {
246                         args.recording_name = (i->value);
247                 } else
248                 {}
249         }
250         ast_ari_recordings_get_stored_file(ser, headers, &args, response);
251 #if defined(AST_DEVMODE)
252         code = response->response_code;
253
254         switch (code) {
255         case 0: /* Implementation is still a stub, or the code wasn't set */
256                 is_valid = response->message == NULL;
257                 break;
258         case 500: /* Internal Server Error */
259         case 501: /* Not Implemented */
260         case 404: /* Recording not found */
261                 is_valid = 1;
262                 break;
263         default:
264                 if (200 <= code && code <= 299) {
265                         /* No validation on a raw binary response */
266                         is_valid = 1;
267                 } else {
268                         ast_log(LOG_ERROR, "Invalid error response %d for /recordings/stored/{recordingName}/file\n", code);
269                         is_valid = 0;
270                 }
271         }
272
273         if (!is_valid) {
274                 ast_log(LOG_ERROR, "Response validation failed for /recordings/stored/{recordingName}/file\n");
275                 ast_ari_response_error(response, 500,
276                         "Internal Server Error", "Response validation failed");
277         }
278 #endif /* AST_DEVMODE */
279
280 fin: __attribute__((unused))
281         return;
282 }
283 int ast_ari_recordings_copy_stored_parse_body(
284         struct ast_json *body,
285         struct ast_ari_recordings_copy_stored_args *args)
286 {
287         struct ast_json *field;
288         /* Parse query parameters out of it */
289         field = ast_json_object_get(body, "destinationRecordingName");
290         if (field) {
291                 args->destination_recording_name = ast_json_string_get(field);
292         }
293         return 0;
294 }
295
296 /*!
297  * \brief Parameter parsing callback for /recordings/stored/{recordingName}/copy.
298  * \param get_params GET parameters in the HTTP request.
299  * \param path_vars Path variables extracted from the request.
300  * \param headers HTTP headers.
301  * \param[out] response Response to the HTTP request.
302  */
303 static void ast_ari_recordings_copy_stored_cb(
304         struct ast_tcptls_session_instance *ser,
305         struct ast_variable *get_params, struct ast_variable *path_vars,
306         struct ast_variable *headers, struct ast_ari_response *response)
307 {
308         struct ast_ari_recordings_copy_stored_args args = {};
309         struct ast_variable *i;
310         RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
311 #if defined(AST_DEVMODE)
312         int is_valid;
313         int code;
314 #endif /* AST_DEVMODE */
315
316         for (i = get_params; i; i = i->next) {
317                 if (strcmp(i->name, "destinationRecordingName") == 0) {
318                         args.destination_recording_name = (i->value);
319                 } else
320                 {}
321         }
322         for (i = path_vars; i; i = i->next) {
323                 if (strcmp(i->name, "recordingName") == 0) {
324                         args.recording_name = (i->value);
325                 } else
326                 {}
327         }
328         /* Look for a JSON request entity */
329         body = ast_http_get_json(ser, headers);
330         if (!body) {
331                 switch (errno) {
332                 case EFBIG:
333                         ast_ari_response_error(response, 413, "Request Entity Too Large", "Request body too large");
334                         goto fin;
335                 case ENOMEM:
336                         ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request");
337                         goto fin;
338                 case EIO:
339                         ast_ari_response_error(response, 400, "Bad Request", "Error parsing request body");
340                         goto fin;
341                 }
342         }
343         if (ast_ari_recordings_copy_stored_parse_body(body, &args)) {
344                 ast_ari_response_alloc_failed(response);
345                 goto fin;
346         }
347         ast_ari_recordings_copy_stored(headers, &args, response);
348 #if defined(AST_DEVMODE)
349         code = response->response_code;
350
351         switch (code) {
352         case 0: /* Implementation is still a stub, or the code wasn't set */
353                 is_valid = response->message == NULL;
354                 break;
355         case 500: /* Internal Server Error */
356         case 501: /* Not Implemented */
357         case 404: /* Recording not found */
358         case 409: /* A recording with the same name already exists on the system */
359                 is_valid = 1;
360                 break;
361         default:
362                 if (200 <= code && code <= 299) {
363                         is_valid = ast_ari_validate_stored_recording(
364                                 response->message);
365                 } else {
366                         ast_log(LOG_ERROR, "Invalid error response %d for /recordings/stored/{recordingName}/copy\n", code);
367                         is_valid = 0;
368                 }
369         }
370
371         if (!is_valid) {
372                 ast_log(LOG_ERROR, "Response validation failed for /recordings/stored/{recordingName}/copy\n");
373                 ast_ari_response_error(response, 500,
374                         "Internal Server Error", "Response validation failed");
375         }
376 #endif /* AST_DEVMODE */
377
378 fin: __attribute__((unused))
379         return;
380 }
381 /*!
382  * \brief Parameter parsing callback for /recordings/live/{recordingName}.
383  * \param get_params GET parameters in the HTTP request.
384  * \param path_vars Path variables extracted from the request.
385  * \param headers HTTP headers.
386  * \param[out] response Response to the HTTP request.
387  */
388 static void ast_ari_recordings_get_live_cb(
389         struct ast_tcptls_session_instance *ser,
390         struct ast_variable *get_params, struct ast_variable *path_vars,
391         struct ast_variable *headers, struct ast_ari_response *response)
392 {
393         struct ast_ari_recordings_get_live_args args = {};
394         struct ast_variable *i;
395         RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
396 #if defined(AST_DEVMODE)
397         int is_valid;
398         int code;
399 #endif /* AST_DEVMODE */
400
401         for (i = path_vars; i; i = i->next) {
402                 if (strcmp(i->name, "recordingName") == 0) {
403                         args.recording_name = (i->value);
404                 } else
405                 {}
406         }
407         ast_ari_recordings_get_live(headers, &args, response);
408 #if defined(AST_DEVMODE)
409         code = response->response_code;
410
411         switch (code) {
412         case 0: /* Implementation is still a stub, or the code wasn't set */
413                 is_valid = response->message == NULL;
414                 break;
415         case 500: /* Internal Server Error */
416         case 501: /* Not Implemented */
417         case 404: /* Recording not found */
418                 is_valid = 1;
419                 break;
420         default:
421                 if (200 <= code && code <= 299) {
422                         is_valid = ast_ari_validate_live_recording(
423                                 response->message);
424                 } else {
425                         ast_log(LOG_ERROR, "Invalid error response %d for /recordings/live/{recordingName}\n", code);
426                         is_valid = 0;
427                 }
428         }
429
430         if (!is_valid) {
431                 ast_log(LOG_ERROR, "Response validation failed for /recordings/live/{recordingName}\n");
432                 ast_ari_response_error(response, 500,
433                         "Internal Server Error", "Response validation failed");
434         }
435 #endif /* AST_DEVMODE */
436
437 fin: __attribute__((unused))
438         return;
439 }
440 /*!
441  * \brief Parameter parsing callback for /recordings/live/{recordingName}.
442  * \param get_params GET parameters in the HTTP request.
443  * \param path_vars Path variables extracted from the request.
444  * \param headers HTTP headers.
445  * \param[out] response Response to the HTTP request.
446  */
447 static void ast_ari_recordings_cancel_cb(
448         struct ast_tcptls_session_instance *ser,
449         struct ast_variable *get_params, struct ast_variable *path_vars,
450         struct ast_variable *headers, struct ast_ari_response *response)
451 {
452         struct ast_ari_recordings_cancel_args args = {};
453         struct ast_variable *i;
454         RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
455 #if defined(AST_DEVMODE)
456         int is_valid;
457         int code;
458 #endif /* AST_DEVMODE */
459
460         for (i = path_vars; i; i = i->next) {
461                 if (strcmp(i->name, "recordingName") == 0) {
462                         args.recording_name = (i->value);
463                 } else
464                 {}
465         }
466         ast_ari_recordings_cancel(headers, &args, response);
467 #if defined(AST_DEVMODE)
468         code = response->response_code;
469
470         switch (code) {
471         case 0: /* Implementation is still a stub, or the code wasn't set */
472                 is_valid = response->message == NULL;
473                 break;
474         case 500: /* Internal Server Error */
475         case 501: /* Not Implemented */
476         case 404: /* Recording not found */
477                 is_valid = 1;
478                 break;
479         default:
480                 if (200 <= code && code <= 299) {
481                         is_valid = ast_ari_validate_void(
482                                 response->message);
483                 } else {
484                         ast_log(LOG_ERROR, "Invalid error response %d for /recordings/live/{recordingName}\n", code);
485                         is_valid = 0;
486                 }
487         }
488
489         if (!is_valid) {
490                 ast_log(LOG_ERROR, "Response validation failed for /recordings/live/{recordingName}\n");
491                 ast_ari_response_error(response, 500,
492                         "Internal Server Error", "Response validation failed");
493         }
494 #endif /* AST_DEVMODE */
495
496 fin: __attribute__((unused))
497         return;
498 }
499 /*!
500  * \brief Parameter parsing callback for /recordings/live/{recordingName}/stop.
501  * \param get_params GET parameters in the HTTP request.
502  * \param path_vars Path variables extracted from the request.
503  * \param headers HTTP headers.
504  * \param[out] response Response to the HTTP request.
505  */
506 static void ast_ari_recordings_stop_cb(
507         struct ast_tcptls_session_instance *ser,
508         struct ast_variable *get_params, struct ast_variable *path_vars,
509         struct ast_variable *headers, struct ast_ari_response *response)
510 {
511         struct ast_ari_recordings_stop_args args = {};
512         struct ast_variable *i;
513         RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
514 #if defined(AST_DEVMODE)
515         int is_valid;
516         int code;
517 #endif /* AST_DEVMODE */
518
519         for (i = path_vars; i; i = i->next) {
520                 if (strcmp(i->name, "recordingName") == 0) {
521                         args.recording_name = (i->value);
522                 } else
523                 {}
524         }
525         ast_ari_recordings_stop(headers, &args, response);
526 #if defined(AST_DEVMODE)
527         code = response->response_code;
528
529         switch (code) {
530         case 0: /* Implementation is still a stub, or the code wasn't set */
531                 is_valid = response->message == NULL;
532                 break;
533         case 500: /* Internal Server Error */
534         case 501: /* Not Implemented */
535         case 404: /* Recording not found */
536                 is_valid = 1;
537                 break;
538         default:
539                 if (200 <= code && code <= 299) {
540                         is_valid = ast_ari_validate_void(
541                                 response->message);
542                 } else {
543                         ast_log(LOG_ERROR, "Invalid error response %d for /recordings/live/{recordingName}/stop\n", code);
544                         is_valid = 0;
545                 }
546         }
547
548         if (!is_valid) {
549                 ast_log(LOG_ERROR, "Response validation failed for /recordings/live/{recordingName}/stop\n");
550                 ast_ari_response_error(response, 500,
551                         "Internal Server Error", "Response validation failed");
552         }
553 #endif /* AST_DEVMODE */
554
555 fin: __attribute__((unused))
556         return;
557 }
558 /*!
559  * \brief Parameter parsing callback for /recordings/live/{recordingName}/pause.
560  * \param get_params GET parameters in the HTTP request.
561  * \param path_vars Path variables extracted from the request.
562  * \param headers HTTP headers.
563  * \param[out] response Response to the HTTP request.
564  */
565 static void ast_ari_recordings_pause_cb(
566         struct ast_tcptls_session_instance *ser,
567         struct ast_variable *get_params, struct ast_variable *path_vars,
568         struct ast_variable *headers, struct ast_ari_response *response)
569 {
570         struct ast_ari_recordings_pause_args args = {};
571         struct ast_variable *i;
572         RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
573 #if defined(AST_DEVMODE)
574         int is_valid;
575         int code;
576 #endif /* AST_DEVMODE */
577
578         for (i = path_vars; i; i = i->next) {
579                 if (strcmp(i->name, "recordingName") == 0) {
580                         args.recording_name = (i->value);
581                 } else
582                 {}
583         }
584         ast_ari_recordings_pause(headers, &args, response);
585 #if defined(AST_DEVMODE)
586         code = response->response_code;
587
588         switch (code) {
589         case 0: /* Implementation is still a stub, or the code wasn't set */
590                 is_valid = response->message == NULL;
591                 break;
592         case 500: /* Internal Server Error */
593         case 501: /* Not Implemented */
594         case 404: /* Recording not found */
595         case 409: /* Recording not in session */
596                 is_valid = 1;
597                 break;
598         default:
599                 if (200 <= code && code <= 299) {
600                         is_valid = ast_ari_validate_void(
601                                 response->message);
602                 } else {
603                         ast_log(LOG_ERROR, "Invalid error response %d for /recordings/live/{recordingName}/pause\n", code);
604                         is_valid = 0;
605                 }
606         }
607
608         if (!is_valid) {
609                 ast_log(LOG_ERROR, "Response validation failed for /recordings/live/{recordingName}/pause\n");
610                 ast_ari_response_error(response, 500,
611                         "Internal Server Error", "Response validation failed");
612         }
613 #endif /* AST_DEVMODE */
614
615 fin: __attribute__((unused))
616         return;
617 }
618 /*!
619  * \brief Parameter parsing callback for /recordings/live/{recordingName}/pause.
620  * \param get_params GET parameters in the HTTP request.
621  * \param path_vars Path variables extracted from the request.
622  * \param headers HTTP headers.
623  * \param[out] response Response to the HTTP request.
624  */
625 static void ast_ari_recordings_unpause_cb(
626         struct ast_tcptls_session_instance *ser,
627         struct ast_variable *get_params, struct ast_variable *path_vars,
628         struct ast_variable *headers, struct ast_ari_response *response)
629 {
630         struct ast_ari_recordings_unpause_args args = {};
631         struct ast_variable *i;
632         RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
633 #if defined(AST_DEVMODE)
634         int is_valid;
635         int code;
636 #endif /* AST_DEVMODE */
637
638         for (i = path_vars; i; i = i->next) {
639                 if (strcmp(i->name, "recordingName") == 0) {
640                         args.recording_name = (i->value);
641                 } else
642                 {}
643         }
644         ast_ari_recordings_unpause(headers, &args, response);
645 #if defined(AST_DEVMODE)
646         code = response->response_code;
647
648         switch (code) {
649         case 0: /* Implementation is still a stub, or the code wasn't set */
650                 is_valid = response->message == NULL;
651                 break;
652         case 500: /* Internal Server Error */
653         case 501: /* Not Implemented */
654         case 404: /* Recording not found */
655         case 409: /* Recording not in session */
656                 is_valid = 1;
657                 break;
658         default:
659                 if (200 <= code && code <= 299) {
660                         is_valid = ast_ari_validate_void(
661                                 response->message);
662                 } else {
663                         ast_log(LOG_ERROR, "Invalid error response %d for /recordings/live/{recordingName}/pause\n", code);
664                         is_valid = 0;
665                 }
666         }
667
668         if (!is_valid) {
669                 ast_log(LOG_ERROR, "Response validation failed for /recordings/live/{recordingName}/pause\n");
670                 ast_ari_response_error(response, 500,
671                         "Internal Server Error", "Response validation failed");
672         }
673 #endif /* AST_DEVMODE */
674
675 fin: __attribute__((unused))
676         return;
677 }
678 /*!
679  * \brief Parameter parsing callback for /recordings/live/{recordingName}/mute.
680  * \param get_params GET parameters in the HTTP request.
681  * \param path_vars Path variables extracted from the request.
682  * \param headers HTTP headers.
683  * \param[out] response Response to the HTTP request.
684  */
685 static void ast_ari_recordings_mute_cb(
686         struct ast_tcptls_session_instance *ser,
687         struct ast_variable *get_params, struct ast_variable *path_vars,
688         struct ast_variable *headers, struct ast_ari_response *response)
689 {
690         struct ast_ari_recordings_mute_args args = {};
691         struct ast_variable *i;
692         RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
693 #if defined(AST_DEVMODE)
694         int is_valid;
695         int code;
696 #endif /* AST_DEVMODE */
697
698         for (i = path_vars; i; i = i->next) {
699                 if (strcmp(i->name, "recordingName") == 0) {
700                         args.recording_name = (i->value);
701                 } else
702                 {}
703         }
704         ast_ari_recordings_mute(headers, &args, response);
705 #if defined(AST_DEVMODE)
706         code = response->response_code;
707
708         switch (code) {
709         case 0: /* Implementation is still a stub, or the code wasn't set */
710                 is_valid = response->message == NULL;
711                 break;
712         case 500: /* Internal Server Error */
713         case 501: /* Not Implemented */
714         case 404: /* Recording not found */
715         case 409: /* Recording not in session */
716                 is_valid = 1;
717                 break;
718         default:
719                 if (200 <= code && code <= 299) {
720                         is_valid = ast_ari_validate_void(
721                                 response->message);
722                 } else {
723                         ast_log(LOG_ERROR, "Invalid error response %d for /recordings/live/{recordingName}/mute\n", code);
724                         is_valid = 0;
725                 }
726         }
727
728         if (!is_valid) {
729                 ast_log(LOG_ERROR, "Response validation failed for /recordings/live/{recordingName}/mute\n");
730                 ast_ari_response_error(response, 500,
731                         "Internal Server Error", "Response validation failed");
732         }
733 #endif /* AST_DEVMODE */
734
735 fin: __attribute__((unused))
736         return;
737 }
738 /*!
739  * \brief Parameter parsing callback for /recordings/live/{recordingName}/mute.
740  * \param get_params GET parameters in the HTTP request.
741  * \param path_vars Path variables extracted from the request.
742  * \param headers HTTP headers.
743  * \param[out] response Response to the HTTP request.
744  */
745 static void ast_ari_recordings_unmute_cb(
746         struct ast_tcptls_session_instance *ser,
747         struct ast_variable *get_params, struct ast_variable *path_vars,
748         struct ast_variable *headers, struct ast_ari_response *response)
749 {
750         struct ast_ari_recordings_unmute_args args = {};
751         struct ast_variable *i;
752         RAII_VAR(struct ast_json *, body, NULL, ast_json_unref);
753 #if defined(AST_DEVMODE)
754         int is_valid;
755         int code;
756 #endif /* AST_DEVMODE */
757
758         for (i = path_vars; i; i = i->next) {
759                 if (strcmp(i->name, "recordingName") == 0) {
760                         args.recording_name = (i->value);
761                 } else
762                 {}
763         }
764         ast_ari_recordings_unmute(headers, &args, response);
765 #if defined(AST_DEVMODE)
766         code = response->response_code;
767
768         switch (code) {
769         case 0: /* Implementation is still a stub, or the code wasn't set */
770                 is_valid = response->message == NULL;
771                 break;
772         case 500: /* Internal Server Error */
773         case 501: /* Not Implemented */
774         case 404: /* Recording not found */
775         case 409: /* Recording not in session */
776                 is_valid = 1;
777                 break;
778         default:
779                 if (200 <= code && code <= 299) {
780                         is_valid = ast_ari_validate_void(
781                                 response->message);
782                 } else {
783                         ast_log(LOG_ERROR, "Invalid error response %d for /recordings/live/{recordingName}/mute\n", code);
784                         is_valid = 0;
785                 }
786         }
787
788         if (!is_valid) {
789                 ast_log(LOG_ERROR, "Response validation failed for /recordings/live/{recordingName}/mute\n");
790                 ast_ari_response_error(response, 500,
791                         "Internal Server Error", "Response validation failed");
792         }
793 #endif /* AST_DEVMODE */
794
795 fin: __attribute__((unused))
796         return;
797 }
798
799 /*! \brief REST handler for /api-docs/recordings.{format} */
800 static struct stasis_rest_handlers recordings_stored_recordingName_file = {
801         .path_segment = "file",
802         .callbacks = {
803                 [AST_HTTP_GET] = ast_ari_recordings_get_stored_file_cb,
804         },
805         .num_children = 0,
806         .children = {  }
807 };
808 /*! \brief REST handler for /api-docs/recordings.{format} */
809 static struct stasis_rest_handlers recordings_stored_recordingName_copy = {
810         .path_segment = "copy",
811         .callbacks = {
812                 [AST_HTTP_POST] = ast_ari_recordings_copy_stored_cb,
813         },
814         .num_children = 0,
815         .children = {  }
816 };
817 /*! \brief REST handler for /api-docs/recordings.{format} */
818 static struct stasis_rest_handlers recordings_stored_recordingName = {
819         .path_segment = "recordingName",
820         .is_wildcard = 1,
821         .callbacks = {
822                 [AST_HTTP_GET] = ast_ari_recordings_get_stored_cb,
823                 [AST_HTTP_DELETE] = ast_ari_recordings_delete_stored_cb,
824         },
825         .num_children = 2,
826         .children = { &recordings_stored_recordingName_file,&recordings_stored_recordingName_copy, }
827 };
828 /*! \brief REST handler for /api-docs/recordings.{format} */
829 static struct stasis_rest_handlers recordings_stored = {
830         .path_segment = "stored",
831         .callbacks = {
832                 [AST_HTTP_GET] = ast_ari_recordings_list_stored_cb,
833         },
834         .num_children = 1,
835         .children = { &recordings_stored_recordingName, }
836 };
837 /*! \brief REST handler for /api-docs/recordings.{format} */
838 static struct stasis_rest_handlers recordings_live_recordingName_stop = {
839         .path_segment = "stop",
840         .callbacks = {
841                 [AST_HTTP_POST] = ast_ari_recordings_stop_cb,
842         },
843         .num_children = 0,
844         .children = {  }
845 };
846 /*! \brief REST handler for /api-docs/recordings.{format} */
847 static struct stasis_rest_handlers recordings_live_recordingName_pause = {
848         .path_segment = "pause",
849         .callbacks = {
850                 [AST_HTTP_POST] = ast_ari_recordings_pause_cb,
851                 [AST_HTTP_DELETE] = ast_ari_recordings_unpause_cb,
852         },
853         .num_children = 0,
854         .children = {  }
855 };
856 /*! \brief REST handler for /api-docs/recordings.{format} */
857 static struct stasis_rest_handlers recordings_live_recordingName_mute = {
858         .path_segment = "mute",
859         .callbacks = {
860                 [AST_HTTP_POST] = ast_ari_recordings_mute_cb,
861                 [AST_HTTP_DELETE] = ast_ari_recordings_unmute_cb,
862         },
863         .num_children = 0,
864         .children = {  }
865 };
866 /*! \brief REST handler for /api-docs/recordings.{format} */
867 static struct stasis_rest_handlers recordings_live_recordingName = {
868         .path_segment = "recordingName",
869         .is_wildcard = 1,
870         .callbacks = {
871                 [AST_HTTP_GET] = ast_ari_recordings_get_live_cb,
872                 [AST_HTTP_DELETE] = ast_ari_recordings_cancel_cb,
873         },
874         .num_children = 3,
875         .children = { &recordings_live_recordingName_stop,&recordings_live_recordingName_pause,&recordings_live_recordingName_mute, }
876 };
877 /*! \brief REST handler for /api-docs/recordings.{format} */
878 static struct stasis_rest_handlers recordings_live = {
879         .path_segment = "live",
880         .callbacks = {
881         },
882         .num_children = 1,
883         .children = { &recordings_live_recordingName, }
884 };
885 /*! \brief REST handler for /api-docs/recordings.{format} */
886 static struct stasis_rest_handlers recordings = {
887         .path_segment = "recordings",
888         .callbacks = {
889         },
890         .num_children = 2,
891         .children = { &recordings_stored,&recordings_live, }
892 };
893
894 static int load_module(void)
895 {
896         int res = 0;
897         stasis_app_ref();
898         res |= ast_ari_add_handler(&recordings);
899         return res;
900 }
901
902 static int unload_module(void)
903 {
904         ast_ari_remove_handler(&recordings);
905         stasis_app_unref();
906         return 0;
907 }
908
909 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "RESTful API module - Recording resources",
910         .support_level = AST_MODULE_SUPPORT_CORE,
911         .load = load_module,
912         .unload = unload_module,
913         .nonoptreq = "res_ari,res_stasis",
914 );