Asterisk - The Open Source Telephony Project  GIT-master-1b41629
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,
60  ao2_cleanup);
61 
62  int r = ast_json_array_append(
63  json, stasis_app_stored_recording_to_json(recording));
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,
80  ao2_cleanup);
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 
91  json = stasis_app_stored_recording_to_json(recording);
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,
107  ao2_cleanup);
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)],
142  ast_ari_response_ok(response, ast_json_null());
143 }
144 
147  struct ast_ari_response *response)
148 {
149  RAII_VAR(struct stasis_app_stored_recording *, src_recording, NULL,
150  ao2_cleanup);
151  RAII_VAR(struct stasis_app_stored_recording *, dst_recording, NULL,
152  ao2_cleanup);
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 
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,
223  ao2_cleanup);
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 
256  ast_ari_response_no_content(response);
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 
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 
283 static 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 
290  recording = stasis_app_recording_find_by_name(name);
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) {
301  ast_ari_response_no_content(response);
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 }
Stasis Application Recording API. See StasisApplication API" for detailed documentation.
struct ast_json * ast_json_ref(struct ast_json *value)
Increase refcount on value.
Definition: json.c:67
enum ast_media_type ast_format_get_type(const struct ast_format *format)
Get the media type of a format.
Definition: format.c:354
Asterisk main include file. File version handling, generic pbx functions.
struct ast_str * headers
Definition: ari.h:95
stasis_app_recording_media_operation
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
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.
#define LOG_WARNING
Definition: logger.h:274
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.
Structure for variables, used for configurations and for channel variables.
static void control_recording(const char *name, enum stasis_app_recording_media_operation operation, struct ast_ari_response *response)
struct ast_json * stasis_app_stored_recording_to_json(struct stasis_app_stored_recording *recording)
Convert stored recording info to JSON.
Definition: stored.c:446
Definition of a media format.
Definition: format.c:43
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:1091
void ao2_iterator_destroy(struct ao2_iterator *iter)
Destroy a container iterator.
const char * args
#define NULL
Definition: resample.c:96
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
struct ao2_container * stasis_app_stored_recording_find_all(void)
Find all stored recordings on disk.
Definition: stored.c:290
struct ast_json * ast_json_null(void)
Get the JSON null value.
Definition: json.c:248
struct ast_json * stasis_app_recording_to_json(const struct stasis_app_recording *recording)
Construct a JSON model of a recording.
#define ast_log
Definition: astobj2.c:42
static struct stasis_rest_handlers recordings
REST handler for /api-docs/recordings.json.
#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:911
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
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_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.
describes a server instance
Definition: tcptls.h:149
struct ast_json * ast_json_array_create(void)
Create a empty JSON array.
Definition: json.c:352
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 ast_json_array_append(struct ast_json *array, struct ast_json *value)
Append to an array.
Definition: json.c:368
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_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_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_get_stored(struct ast_variable *headers, struct ast_ari_recordings_get_stored_args *args, struct ast_ari_response *response)
Get a stored recording&#39;s details.
int errno
stasis_app_recording_oper_results
Possible results from a recording operation.
#define ao2_iterator_next(iter)
Definition: astobj2.h:1933
static const char name[]
Definition: cdr_mysql.c:74
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
int stasis_app_stored_recording_delete(struct stasis_app_stored_recording *recording)
Delete a recording from disk.
Definition: stored.c:439
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
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:1937
struct ast_json * message
Definition: ari.h:93
When we need to walk through a container, we use an ao2_iterator to keep track of the current positio...
Definition: astobj2.h:1841
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
Generated file - declares stubs to be implemented in res/ari/resource_recordings.c.
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:389
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:310
Abstract JSON element (object, array, string, int, ...).
struct stasis_app_recording * stasis_app_recording_find_by_name(const char *name)
Finds the recording object with the given name.
Generic container type.
static snd_pcm_format_t format
Definition: chan_alsa.c:102
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.
struct ao2_iterator ao2_iterator_init(struct ao2_container *c, int flags) attribute_warn_unused_result
Create an iterator for a container.
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.
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.
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_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_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.