resource_recordings.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  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. /*! \file
  19. *
  20. * \brief /api-docs/recordings.{format} implementation- Recording resources
  21. *
  22. * \author David M. Lee, II <dlee@digium.com>
  23. */
  24. #include "asterisk.h"
  25. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  26. #include "asterisk/stasis_app_recording.h"
  27. #include "resource_recordings.h"
  28. void ast_ari_recordings_list_stored(struct ast_variable *headers,
  29. struct ast_ari_recordings_list_stored_args *args,
  30. struct ast_ari_response *response)
  31. {
  32. RAII_VAR(struct ao2_container *, recordings, NULL, ao2_cleanup);
  33. RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
  34. struct ao2_iterator i;
  35. void *obj;
  36. recordings = stasis_app_stored_recording_find_all();
  37. if (!recordings) {
  38. ast_ari_response_alloc_failed(response);
  39. return;
  40. }
  41. json = ast_json_array_create();
  42. if (!json) {
  43. ast_ari_response_alloc_failed(response);
  44. return;
  45. }
  46. i = ao2_iterator_init(recordings, 0);
  47. while ((obj = ao2_iterator_next(&i))) {
  48. RAII_VAR(struct stasis_app_stored_recording *, recording, obj,
  49. ao2_cleanup);
  50. int r = ast_json_array_append(
  51. json, stasis_app_stored_recording_to_json(recording));
  52. if (r != 0) {
  53. ast_ari_response_alloc_failed(response);
  54. ao2_iterator_destroy(&i);
  55. return;
  56. }
  57. }
  58. ao2_iterator_destroy(&i);
  59. ast_ari_response_ok(response, ast_json_ref(json));
  60. }
  61. void ast_ari_recordings_get_stored(struct ast_variable *headers,
  62. struct ast_ari_recordings_get_stored_args *args,
  63. struct ast_ari_response *response)
  64. {
  65. RAII_VAR(struct stasis_app_stored_recording *, recording, NULL,
  66. ao2_cleanup);
  67. struct ast_json *json;
  68. recording = stasis_app_stored_recording_find_by_name(
  69. args->recording_name);
  70. if (recording == NULL) {
  71. ast_ari_response_error(response, 404, "Not Found",
  72. "Recording not found");
  73. return;
  74. }
  75. json = stasis_app_stored_recording_to_json(recording);
  76. if (json == NULL) {
  77. ast_ari_response_error(response, 500,
  78. "Internal Server Error", "Error building response");
  79. return;
  80. }
  81. ast_ari_response_ok(response, json);
  82. }
  83. void ast_ari_recordings_copy_stored(struct ast_variable *headers,
  84. struct ast_ari_recordings_copy_stored_args *args,
  85. struct ast_ari_response *response)
  86. {
  87. RAII_VAR(struct stasis_app_stored_recording *, src_recording, NULL,
  88. ao2_cleanup);
  89. RAII_VAR(struct stasis_app_stored_recording *, dst_recording, NULL,
  90. ao2_cleanup);
  91. struct ast_json *json;
  92. int res;
  93. src_recording = stasis_app_stored_recording_find_by_name(
  94. args->recording_name);
  95. if (src_recording == NULL) {
  96. ast_ari_response_error(response, 404, "Not Found",
  97. "Recording not found");
  98. return;
  99. }
  100. dst_recording = stasis_app_stored_recording_find_by_name(
  101. args->destination_recording_name);
  102. if (dst_recording) {
  103. ast_ari_response_error(response, 409, "Conflict",
  104. "A recording with the same name already exists on the system");
  105. return;
  106. }
  107. /* See if we got our name rejected */
  108. switch (errno) {
  109. case EINVAL:
  110. ast_ari_response_error(response, 400, "Bad request",
  111. "Invalid destination recording name");
  112. return;
  113. case EACCES:
  114. ast_ari_response_error(response, 403, "Forbidden",
  115. "Destination file path is forbidden");
  116. return;
  117. default:
  118. break;
  119. }
  120. res = stasis_app_stored_recording_copy(src_recording,
  121. args->destination_recording_name, &dst_recording);
  122. if (res) {
  123. switch (errno) {
  124. case EACCES:
  125. case EPERM:
  126. ast_ari_response_error(response, 500,
  127. "Internal Server Error",
  128. "Copy failed");
  129. break;
  130. default:
  131. ast_log(LOG_WARNING,
  132. "Unexpected error copying recording %s to %s: %s\n",
  133. args->recording_name, args->destination_recording_name, strerror(errno));
  134. ast_ari_response_error(response, 500,
  135. "Internal Server Error",
  136. "Copy failed");
  137. break;
  138. }
  139. return;
  140. }
  141. json = stasis_app_stored_recording_to_json(dst_recording);
  142. if (json == NULL) {
  143. ast_ari_response_error(response, 500,
  144. "Internal Server Error", "Error building response");
  145. return;
  146. }
  147. ast_ari_response_ok(response, json);
  148. }
  149. void ast_ari_recordings_delete_stored(struct ast_variable *headers,
  150. struct ast_ari_recordings_delete_stored_args *args,
  151. struct ast_ari_response *response)
  152. {
  153. RAII_VAR(struct stasis_app_stored_recording *, recording, NULL,
  154. ao2_cleanup);
  155. int res;
  156. recording = stasis_app_stored_recording_find_by_name(
  157. args->recording_name);
  158. if (recording == NULL) {
  159. ast_ari_response_error(response, 404, "Not Found",
  160. "Recording not found");
  161. return;
  162. }
  163. res = stasis_app_stored_recording_delete(recording);
  164. if (res != 0) {
  165. switch (errno) {
  166. case EACCES:
  167. case EPERM:
  168. ast_ari_response_error(response, 500,
  169. "Internal Server Error",
  170. "Delete failed");
  171. break;
  172. default:
  173. ast_log(LOG_WARNING,
  174. "Unexpected error deleting recording %s: %s\n",
  175. args->recording_name, strerror(errno));
  176. ast_ari_response_error(response, 500,
  177. "Internal Server Error",
  178. "Delete failed");
  179. break;
  180. }
  181. return;
  182. }
  183. ast_ari_response_no_content(response);
  184. }
  185. void ast_ari_recordings_get_live(struct ast_variable *headers,
  186. struct ast_ari_recordings_get_live_args *args,
  187. struct ast_ari_response *response)
  188. {
  189. RAII_VAR(struct stasis_app_recording *, recording, NULL, ao2_cleanup);
  190. struct ast_json *json;
  191. recording = stasis_app_recording_find_by_name(args->recording_name);
  192. if (recording == NULL) {
  193. ast_ari_response_error(response, 404, "Not Found",
  194. "Recording not found");
  195. return;
  196. }
  197. json = stasis_app_recording_to_json(recording);
  198. if (json == NULL) {
  199. ast_ari_response_error(response, 500,
  200. "Internal Server Error", "Error building response");
  201. return;
  202. }
  203. ast_ari_response_ok(response, json);
  204. }
  205. static void control_recording(const char *name,
  206. enum stasis_app_recording_media_operation operation,
  207. struct ast_ari_response *response)
  208. {
  209. RAII_VAR(struct stasis_app_recording *, recording, NULL, ao2_cleanup);
  210. enum stasis_app_recording_oper_results res;
  211. recording = stasis_app_recording_find_by_name(name);
  212. if (recording == NULL) {
  213. ast_ari_response_error(response, 404, "Not Found",
  214. "Recording not found");
  215. return;
  216. }
  217. res = stasis_app_recording_operation(recording, operation);
  218. switch (res) {
  219. case STASIS_APP_RECORDING_OPER_OK:
  220. ast_ari_response_no_content(response);
  221. return;
  222. case STASIS_APP_RECORDING_OPER_FAILED:
  223. ast_ari_response_error(response, 500,
  224. "Internal Server Error", "Recording operation failed");
  225. return;
  226. case STASIS_APP_RECORDING_OPER_NOT_RECORDING:
  227. ast_ari_response_error(response, 409,
  228. "Conflict", "Recording not in session");
  229. }
  230. }
  231. void ast_ari_recordings_cancel(struct ast_variable *headers,
  232. struct ast_ari_recordings_cancel_args *args,
  233. struct ast_ari_response *response)
  234. {
  235. control_recording(args->recording_name, STASIS_APP_RECORDING_CANCEL,
  236. response);
  237. }
  238. void ast_ari_recordings_stop(struct ast_variable *headers,
  239. struct ast_ari_recordings_stop_args *args,
  240. struct ast_ari_response *response)
  241. {
  242. control_recording(args->recording_name, STASIS_APP_RECORDING_STOP,
  243. response);
  244. }
  245. void ast_ari_recordings_pause(struct ast_variable *headers,
  246. struct ast_ari_recordings_pause_args *args,
  247. struct ast_ari_response *response)
  248. {
  249. control_recording(args->recording_name, STASIS_APP_RECORDING_PAUSE,
  250. response);
  251. }
  252. void ast_ari_recordings_unpause(struct ast_variable *headers,
  253. struct ast_ari_recordings_unpause_args *args,
  254. struct ast_ari_response *response)
  255. {
  256. control_recording(args->recording_name, STASIS_APP_RECORDING_UNPAUSE,
  257. response);
  258. }
  259. void ast_ari_recordings_mute(struct ast_variable *headers,
  260. struct ast_ari_recordings_mute_args *args,
  261. struct ast_ari_response *response)
  262. {
  263. control_recording(args->recording_name, STASIS_APP_RECORDING_MUTE,
  264. response);
  265. }
  266. void ast_ari_recordings_unmute(struct ast_variable *headers,
  267. struct ast_ari_recordings_unmute_args *args,
  268. struct ast_ari_response *response)
  269. {
  270. control_recording(args->recording_name, STASIS_APP_RECORDING_UNMUTE,
  271. response);
  272. }