Asterisk - The Open Source Telephony Project GIT-master-a358458
resource_recordings.c
Go to the documentation of this file.
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/*! \file
20 *
21 * \brief /api-docs/recordings.{format} implementation- Recording resources
22 *
23 * \author David M. Lee, II <dlee@digium.com>
24 */
25
26/*** MODULEINFO
27 <support_level>core</support_level>
28 ***/
29
30#include "asterisk.h"
31
33#include "resource_recordings.h"
34
37 struct ast_ari_response *response)
38{
40 RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
41 struct ao2_iterator i;
42 void *obj;
43
45
46 if (!recordings) {
48 return;
49 }
50
51 json = ast_json_array_create();
52 if (!json) {
54 return;
55 }
56
58 while ((obj = ao2_iterator_next(&i))) {
59 RAII_VAR(struct stasis_app_stored_recording *, recording, obj,
61
64 if (r != 0) {
67 return;
68 }
69 }
71
72 ast_ari_response_ok(response, ast_json_ref(json));
73}
74
77 struct ast_ari_response *response)
78{
79 RAII_VAR(struct stasis_app_stored_recording *, recording, NULL,
81 struct ast_json *json;
82
84 args->recording_name);
85 if (recording == NULL) {
86 ast_ari_response_error(response, 404, "Not Found",
87 "Recording not found");
88 return;
89 }
90
92 if (json == NULL) {
93 ast_ari_response_error(response, 500,
94 "Internal Server Error", "Error building response");
95 return;
96 }
97
98 ast_ari_response_ok(response, json);
99}
100
103 struct ast_ari_response *response)
104{
105 RAII_VAR(struct stasis_app_stored_recording *, recording,
108 static const char *format_type_names[AST_MEDIA_TYPE_TEXT + 1] = {
109 [AST_MEDIA_TYPE_UNKNOWN] = "binary",
110 [AST_MEDIA_TYPE_AUDIO] = "audio",
111 [AST_MEDIA_TYPE_VIDEO] = "video",
112 [AST_MEDIA_TYPE_IMAGE] = "image",
113 [AST_MEDIA_TYPE_TEXT] = "text",
114 };
115 struct ast_format *format;
116
117 response->message = ast_json_null();
118
119 if (!recording) {
120 ast_ari_response_error(response, 404, "Not Found",
121 "Recording not found");
122 return;
123 }
124
126 if (!format) {
127 ast_ari_response_error(response, 500, "Internal Server Error",
128 "Format specified by recording not available or loaded");
129 return;
130 }
131
132 response->fd = open(stasis_app_stored_recording_get_filename(recording), O_RDONLY);
133 if (response->fd < 0) {
134 ast_ari_response_error(response, 403, "Forbidden",
135 "Recording could not be opened");
136 return;
137 }
138
139 ast_str_append(&response->headers, 0, "Content-Type: %s/%s\r\n",
140 format_type_names[ast_format_get_type(format)],
143}
144
147 struct ast_ari_response *response)
148{
149 RAII_VAR(struct stasis_app_stored_recording *, src_recording, NULL,
151 RAII_VAR(struct stasis_app_stored_recording *, dst_recording, NULL,
153 struct ast_json *json;
154 int res;
155
157 args->recording_name);
158 if (src_recording == NULL) {
159 ast_ari_response_error(response, 404, "Not Found",
160 "Recording not found");
161 return;
162 }
163
165 args->destination_recording_name);
166 if (dst_recording) {
167 ast_ari_response_error(response, 409, "Conflict",
168 "A recording with the same name already exists on the system");
169 return;
170 }
171
172 /* See if we got our name rejected */
173 switch (errno) {
174 case EINVAL:
175 ast_ari_response_error(response, 400, "Bad request",
176 "Invalid destination recording name");
177 return;
178 case EACCES:
179 ast_ari_response_error(response, 403, "Forbidden",
180 "Destination file path is forbidden");
181 return;
182 default:
183 break;
184 }
185
186 res = stasis_app_stored_recording_copy(src_recording,
187 args->destination_recording_name, &dst_recording);
188 if (res) {
189 switch (errno) {
190 case EACCES:
191 case EPERM:
192 ast_ari_response_error(response, 500,
193 "Internal Server Error",
194 "Copy failed");
195 break;
196 default:
198 "Unexpected error copying recording %s to %s: %s\n",
199 args->recording_name, args->destination_recording_name, strerror(errno));
200 ast_ari_response_error(response, 500,
201 "Internal Server Error",
202 "Copy failed");
203 break;
204 }
205 return;
206 }
207
208 json = stasis_app_stored_recording_to_json(dst_recording);
209 if (json == NULL) {
210 ast_ari_response_error(response, 500,
211 "Internal Server Error", "Error building response");
212 return;
213 }
214
215 ast_ari_response_ok(response, json);
216}
217
220 struct ast_ari_response *response)
221{
222 RAII_VAR(struct stasis_app_stored_recording *, recording, NULL,
224 int res;
225
227 args->recording_name);
228 if (recording == NULL) {
229 ast_ari_response_error(response, 404, "Not Found",
230 "Recording not found");
231 return;
232 }
233
234 res = stasis_app_stored_recording_delete(recording);
235
236 if (res != 0) {
237 switch (errno) {
238 case EACCES:
239 case EPERM:
240 ast_ari_response_error(response, 500,
241 "Internal Server Error",
242 "Delete failed");
243 break;
244 default:
246 "Unexpected error deleting recording %s: %s\n",
247 args->recording_name, strerror(errno));
248 ast_ari_response_error(response, 500,
249 "Internal Server Error",
250 "Delete failed");
251 break;
252 }
253 return;
254 }
255
257}
258
261 struct ast_ari_response *response)
262{
263 RAII_VAR(struct stasis_app_recording *, recording, NULL, ao2_cleanup);
264 struct ast_json *json;
265
266 recording = stasis_app_recording_find_by_name(args->recording_name);
267 if (recording == NULL) {
268 ast_ari_response_error(response, 404, "Not Found",
269 "Recording not found");
270 return;
271 }
272
273 json = stasis_app_recording_to_json(recording);
274 if (json == NULL) {
275 ast_ari_response_error(response, 500,
276 "Internal Server Error", "Error building response");
277 return;
278 }
279
280 ast_ari_response_ok(response, json);
281}
282
283static void control_recording(const char *name,
285 struct ast_ari_response *response)
286{
287 RAII_VAR(struct stasis_app_recording *, recording, NULL, ao2_cleanup);
289
291 if (recording == NULL) {
292 ast_ari_response_error(response, 404, "Not Found",
293 "Recording not found");
294 return;
295 }
296
297 res = stasis_app_recording_operation(recording, operation);
298
299 switch (res) {
302 return;
304 ast_ari_response_error(response, 500,
305 "Internal Server Error", "Recording operation failed");
306 return;
308 ast_ari_response_error(response, 409,
309 "Conflict", "Recording not in session");
310 }
311}
312
315 struct ast_ari_response *response)
316{
318 response);
319}
320
323 struct ast_ari_response *response)
324{
326 response);
327}
328
331 struct ast_ari_response *response)
332{
334 response);
335}
336
339 struct ast_ari_response *response)
340{
342 response);
343}
344
347 struct ast_ari_response *response)
348{
350 response);
351}
352
355 struct ast_ari_response *response)
356{
358 response);
359}
void ast_ari_response_error(struct ast_ari_response *response, int response_code, const char *response_text, const char *message_fmt,...)
Fill in an error ast_ari_response.
Definition: res_ari.c:259
void ast_ari_response_ok(struct ast_ari_response *response, struct ast_json *message)
Fill in an OK (200) ast_ari_response.
Definition: res_ari.c:276
void ast_ari_response_alloc_failed(struct ast_ari_response *response)
Fill in response with a 500 message for allocation failures.
Definition: res_ari.c:298
void ast_ari_response_no_content(struct ast_ari_response *response)
Fill in a No Content (204) ast_ari_response.
Definition: res_ari.c:284
Asterisk main include file. File version handling, generic pbx functions.
#define ast_log
Definition: astobj2.c:42
#define ao2_iterator_next(iter)
Definition: astobj2.h:1911
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
@ AST_MEDIA_TYPE_AUDIO
Definition: codec.h:32
@ AST_MEDIA_TYPE_UNKNOWN
Definition: codec.h:31
@ AST_MEDIA_TYPE_VIDEO
Definition: codec.h:33
@ AST_MEDIA_TYPE_IMAGE
Definition: codec.h:34
@ AST_MEDIA_TYPE_TEXT
Definition: codec.h:35
struct ast_format * ast_get_format_for_file_ext(const char *file_ext)
Get the ast_format associated with the given file extension.
Definition: file.c:2006
enum ast_media_type ast_format_get_type(const struct ast_format *format)
Get the media type of a format.
Definition: format.c:354
static const char name[]
Definition: format_mp3.c:68
#define LOG_WARNING
struct ast_json * ast_json_null(void)
Get the JSON null value.
Definition: json.c:248
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
int ast_json_array_append(struct ast_json *array, struct ast_json *value)
Append to an array.
Definition: json.c:378
struct ast_json * ast_json_array_create(void)
Create a empty JSON array.
Definition: json.c:362
struct ast_json * ast_json_ref(struct ast_json *value)
Increase refcount on value.
Definition: json.c:67
int errno
static struct stasis_rest_handlers recordings
REST handler for /api-docs/recordings.json.
#define NULL
Definition: resample.c:96
void ast_ari_recordings_unmute(struct ast_variable *headers, struct ast_ari_recordings_unmute_args *args, struct ast_ari_response *response)
Unmute a live recording.
void ast_ari_recordings_cancel(struct ast_variable *headers, struct ast_ari_recordings_cancel_args *args, struct ast_ari_response *response)
Stop a live recording and discard it.
void ast_ari_recordings_pause(struct ast_variable *headers, struct ast_ari_recordings_pause_args *args, struct ast_ari_response *response)
Pause a live recording.
void ast_ari_recordings_copy_stored(struct ast_variable *headers, struct ast_ari_recordings_copy_stored_args *args, struct ast_ari_response *response)
Copy a stored recording.
void ast_ari_recordings_unpause(struct ast_variable *headers, struct ast_ari_recordings_unpause_args *args, struct ast_ari_response *response)
Unpause a live recording.
void ast_ari_recordings_mute(struct ast_variable *headers, struct ast_ari_recordings_mute_args *args, struct ast_ari_response *response)
Mute a live recording.
void ast_ari_recordings_delete_stored(struct ast_variable *headers, struct ast_ari_recordings_delete_stored_args *args, struct ast_ari_response *response)
Delete a stored recording.
void ast_ari_recordings_get_stored(struct ast_variable *headers, struct ast_ari_recordings_get_stored_args *args, struct ast_ari_response *response)
Get a stored recording's details.
void ast_ari_recordings_get_live(struct ast_variable *headers, struct ast_ari_recordings_get_live_args *args, struct ast_ari_response *response)
List live recordings.
void ast_ari_recordings_get_stored_file(struct ast_tcptls_session_instance *ser, struct ast_variable *headers, struct ast_ari_recordings_get_stored_file_args *args, struct ast_ari_response *response)
Get the file associated with the stored recording.
static void control_recording(const char *name, enum stasis_app_recording_media_operation operation, struct ast_ari_response *response)
void ast_ari_recordings_list_stored(struct ast_variable *headers, struct ast_ari_recordings_list_stored_args *args, struct ast_ari_response *response)
List recordings that are complete.
void ast_ari_recordings_stop(struct ast_variable *headers, struct ast_ari_recordings_stop_args *args, struct ast_ari_response *response)
Stop a live recording and store it.
Generated file - declares stubs to be implemented in res/ari/resource_recordings.c.
Stasis Application Recording API. See StasisApplication API" for detailed documentation.
const char * stasis_app_stored_recording_get_filename(struct stasis_app_stored_recording *recording)
Returns the full filename, with extension, for this recording.
Definition: stored.c:62
struct ast_json * stasis_app_recording_to_json(const struct stasis_app_recording *recording)
Construct a JSON model of a recording.
struct ao2_container * stasis_app_stored_recording_find_all(void)
Find all stored recordings on disk.
Definition: stored.c:297
struct ast_json * stasis_app_stored_recording_to_json(struct stasis_app_stored_recording *recording)
Convert stored recording info to JSON.
Definition: stored.c:455
struct stasis_app_stored_recording * stasis_app_stored_recording_find_by_name(const char *name)
Creates a stored recording object, with the given name.
Definition: stored.c:318
struct stasis_app_recording * stasis_app_recording_find_by_name(const char *name)
Finds the recording object with the given name.
int stasis_app_stored_recording_delete(struct stasis_app_stored_recording *recording)
Delete a recording from disk.
Definition: stored.c:448
enum stasis_app_recording_oper_results stasis_app_recording_operation(struct stasis_app_recording *recording, enum stasis_app_recording_media_operation operation)
Controls the media for a given recording operation.
stasis_app_recording_oper_results
Possible results from a recording operation.
@ STASIS_APP_RECORDING_OPER_NOT_RECORDING
@ STASIS_APP_RECORDING_OPER_FAILED
@ STASIS_APP_RECORDING_OPER_OK
const char * stasis_app_stored_recording_get_extension(struct stasis_app_stored_recording *recording)
Returns the extension for this recording.
Definition: stored.c:71
int stasis_app_stored_recording_copy(struct stasis_app_stored_recording *src_recording, const char *dst, struct stasis_app_stored_recording **dst_recording)
Copy a recording.
Definition: stored.c:398
stasis_app_recording_media_operation
@ STASIS_APP_RECORDING_PAUSE
@ STASIS_APP_RECORDING_UNPAUSE
@ STASIS_APP_RECORDING_UNMUTE
@ STASIS_APP_RECORDING_STOP
@ STASIS_APP_RECORDING_MUTE
@ STASIS_APP_RECORDING_CANCEL
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1139
Generic container type.
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1821
struct ast_str * headers
Definition: ari.h:96
struct ast_json * message
Definition: ari.h:94
Definition of a media format.
Definition: format.c:43
Abstract JSON element (object, array, string, int, ...).
describes a server instance
Definition: tcptls.h:150
Structure for variables, used for configurations and for channel variables.
const char * args
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941