resource_recordings.c 8.3 KB

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