Multiple revisions 420089-420090,420097
[asterisk/asterisk.git] / res / ari / resource_channels.c
index 0f4486b..d0a1be3 100644 (file)
@@ -42,6 +42,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/stasis_app_snoop.h"
 #include "asterisk/stasis_channels.h"
 #include "asterisk/causes.h"
+#include "asterisk/format_cache.h"
+#include "asterisk/core_local.h"
 #include "resource_channels.h"
 
 #include <limits.h>
@@ -411,9 +413,9 @@ static void ari_channels_handle_play(
                return;
        }
 
-       ast_asprintf(&playback_url, "/playback/%s",
-               stasis_app_playback_get_id(playback));
-       if (!playback_url) {
+       if (ast_asprintf(&playback_url, "/playback/%s",
+                       stasis_app_playback_get_id(playback)) == -1) {
+               playback_url = NULL;
                ast_ari_response_error(
                        response, 500, "Internal Server Error",
                        "Out of memory");
@@ -464,7 +466,6 @@ void ast_ari_channels_record(struct ast_variable *headers,
        struct ast_ari_response *response)
 {
        RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
-       RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
        RAII_VAR(struct stasis_app_recording *, recording, NULL, ao2_cleanup);
        RAII_VAR(char *, recording_url, NULL, ast_free);
        struct ast_json *json;
@@ -580,8 +581,9 @@ void ast_ari_channels_record(struct ast_variable *headers,
        ast_uri_encode(args->name, uri_encoded_name, uri_name_maxlen,
                ast_uri_http);
 
-       ast_asprintf(&recording_url, "/recordings/live/%s", uri_encoded_name);
-       if (!recording_url) {
+       if (ast_asprintf(&recording_url, "/recordings/live/%s",
+                       uri_encoded_name) == -1) {
+               recording_url = NULL;
                ast_ari_response_error(
                        response, 500, "Internal Server Error",
                        "Out of memory");
@@ -721,36 +723,6 @@ void ast_ari_channels_list(struct ast_variable *headers,
        ast_ari_response_ok(response, ast_json_ref(json));
 }
 
-static int json_to_ast_variables(struct ast_json *json_variables, struct ast_variable **variables)
-{
-       struct ast_variable *current = NULL;
-       struct ast_json_iter *it_json_var;
-
-       for (it_json_var = ast_json_object_iter(json_variables); it_json_var;
-                it_json_var = ast_json_object_iter_next(json_variables, it_json_var)) {
-               struct ast_variable *new_var;
-
-               new_var = ast_variable_new(ast_json_object_iter_key(it_json_var),
-                                                                  ast_json_string_get(ast_json_object_iter_value(it_json_var)),
-                                                                  "");
-               if (!new_var) {
-                       ast_variables_destroy(*variables);
-                       *variables = NULL;
-                       return 1;
-               }
-
-               if (!current) {
-                       *variables = new_var;
-                       current = *variables;
-               } else {
-                       current->next = new_var;
-                       current = new_var;
-               }
-       }
-
-       return 0;
-}
-
 static void ari_channels_handle_originate_with_id(const char *args_endpoint,
        const char *args_extension,
        const char *args_context,
@@ -771,23 +743,28 @@ static void ari_channels_handle_originate_with_id(const char *args_endpoint,
        char *cid_name = NULL;
        int timeout = 30000;
        RAII_VAR(struct ast_format_cap *, cap,
-               ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK), ast_format_cap_destroy);
-       struct ast_format tmp_fmt;
+               ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT), ao2_cleanup);
        char *stuff;
        struct ast_channel *chan;
+       struct ast_channel *local_peer;
        RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
-       struct ast_assigned_ids assignedids = {args_channel_id, args_other_channel_id};
-
-       if ((!ast_strlen_zero(assignedids.uniqueid) && strlen(assignedids.uniqueid) >= AST_MAX_UNIQUEID) || 
-               (!ast_strlen_zero(assignedids.uniqueid2) && strlen(assignedids.uniqueid2) >= AST_MAX_UNIQUEID)) {
-               ast_log(LOG_WARNING, "Uniqueid length exceeds maximum of %d\n", AST_MAX_UNIQUEID);
-       }
+       struct ast_assigned_ids assignedids = {
+               .uniqueid = args_channel_id,
+               .uniqueid2 = args_other_channel_id,
+       };
 
        if (!cap) {
                ast_ari_response_alloc_failed(response);
                return;
        }
-       ast_format_cap_add(cap, ast_format_set(&tmp_fmt, AST_FORMAT_SLINEAR, 0));
+       ast_format_cap_append(cap, ast_format_slin, 0);
+
+       if ((assignedids.uniqueid && AST_MAX_PUBLIC_UNIQUEID < strlen(assignedids.uniqueid))
+               || (assignedids.uniqueid2 && AST_MAX_PUBLIC_UNIQUEID < strlen(assignedids.uniqueid2))) {
+               ast_ari_response_error(response, 400, "Bad Request",
+                       "Uniqueid length exceeds maximum of %d", AST_MAX_PUBLIC_UNIQUEID);
+               return;
+       }
 
        if (ast_strlen_zero(args_endpoint)) {
                ast_ari_response_error(response, 400, "Bad Request",
@@ -854,20 +831,24 @@ static void ari_channels_handle_originate_with_id(const char *args_endpoint,
                return;
        }
 
-       snapshot = ast_channel_snapshot_create(chan);
-       ast_channel_unlock(chan);
+       /* See if this is a Local channel and if so, get the peer */
+       local_peer = ast_local_get_peer(chan);
 
        if (!ast_strlen_zero(args_app)) {
-               /* channel: + channel ID + null terminator */
-               char uri[9 + strlen(ast_channel_uniqueid(chan))];
-               const char *uris[1] = { uri, };
-
-               sprintf(uri, "channel:%s", ast_channel_uniqueid(chan));
-               stasis_app_subscribe(args_app, uris, 1, NULL);
+               stasis_app_subscribe_channel(args_app, chan);
+               if (local_peer) {
+                       stasis_app_subscribe_channel(args_app, local_peer);
+               }
        }
 
+       snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(chan));
+       ast_channel_unlock(chan);
+
        ast_ari_response_ok(response, ast_channel_snapshot_to_json(snapshot, NULL));
        ast_channel_unref(chan);
+       if (local_peer) {
+               ast_channel_unref(local_peer);
+       }
 }
 
 void ast_ari_channels_originate_with_id(struct ast_variable *headers,
@@ -883,7 +864,7 @@ void ast_ari_channels_originate_with_id(struct ast_variable *headers,
                ast_ari_channels_originate_with_id_parse_body(args->variables, args);
                json_variables = ast_json_object_get(args->variables, "variables");
                if (json_variables) {
-                       if (json_to_ast_variables(json_variables, &variables)) {
+                       if (ast_json_to_ast_variables(json_variables, &variables)) {
                                ast_log(AST_LOG_ERROR, "Unable to convert 'variables' in JSON body to channel variables\n");
                                ast_ari_response_alloc_failed(response);
                                return;
@@ -919,7 +900,7 @@ void ast_ari_channels_originate(struct ast_variable *headers,
                ast_ari_channels_originate_parse_body(args->variables, args);
                json_variables = ast_json_object_get(args->variables, "variables");
                if (json_variables) {
-                       if (json_to_ast_variables(json_variables, &variables)) {
+                       if (ast_json_to_ast_variables(json_variables, &variables)) {
                                ast_log(AST_LOG_ERROR, "Unable to convert 'variables' in JSON body to channel variables\n");
                                ast_ari_response_alloc_failed(response);
                                return;
@@ -1081,7 +1062,7 @@ static void ari_channels_handle_snoop_channel(
                return;
        }
 
-       snapshot = ast_channel_snapshot_create(snoop);
+       snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(snoop));
        ast_ari_response_ok(response, ast_channel_snapshot_to_json(snapshot, NULL));
 }