ari/resource_channels: Add channel variables earlier in the creation process
authorMatthew Jordan <mjordan@digium.com>
Tue, 11 Feb 2014 03:18:25 +0000 (03:18 +0000)
committerMatthew Jordan <mjordan@digium.com>
Tue, 11 Feb 2014 03:18:25 +0000 (03:18 +0000)
This patch tweaks the behaviour of POST /channels with channel variables such
that the variables are passed into the pbx.c routines that perform the
origination. This allows the variables to be assigned to the newly created
channels immediately upon their construction, as opposed to be assigned after
the originate has completed.

The upshot of this is that the variables are available on the channels if
they execute in the dialplan, as opposed to only being available once the
channels are answered.

Review: https://reviewboard.asterisk.org/r/3183/
........

Merged revisions 407937 from http://svn.asterisk.org/svn/asterisk/branches/12

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@407940 65c4cc65-6c06-0410-ace0-fbb531ad65f3

res/ari/resource_channels.c

index ab8f5b4..97d9bb3 100644 (file)
@@ -687,37 +687,30 @@ void ast_ari_channels_list(struct ast_variable *headers,
        ast_ari_response_ok(response, ast_json_ref(json));
 }
 
-static int ari_channels_set_channel_var(struct ast_channel *chan,
-       const char *variable, const char *value, struct ast_ari_response *response)
+static int json_to_ast_variables(struct ast_json *json_variables, struct ast_variable **variables)
 {
-       if (pbx_builtin_setvar_helper(chan, variable, value)) {
-               ast_ari_response_error(
-                       response, 400, "Bad Request",
-                       "Unable to set channel variable %s=%s", variable, value);
-               return -1;
-       }
-
-       return 0;
-}
-
-static int ari_channels_set_channel_vars(struct ast_channel *chan,
-       struct ast_json *variables, struct ast_ari_response *response)
-{
-       struct ast_json_iter *i;
-
-       if (!variables) {
-               /* nothing to do */
-               return 0;
-       }
+       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;
+               }
 
-       for (i = ast_json_object_iter(variables); i;
-            i = ast_json_object_iter_next(variables, i)) {
-               if (ari_channels_set_channel_var(
-                       chan, ast_json_object_iter_key(i),
-                       ast_json_string_get(ast_json_object_iter_value(i)),
-                       response)) {
-                       /* response filled in by called function */
-                       return -1;
+               if (!current) {
+                       *variables = new_var;
+                       current = *variables;
+               } else {
+                       current->next = new_var;
+                       current = new_var;
                }
        }
 
@@ -737,11 +730,10 @@ void ast_ari_channels_originate(struct ast_variable *headers,
        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;
-
+       RAII_VAR(struct ast_variable *, variables, NULL, ast_variables_destroy);
        char *stuff;
        struct ast_channel *chan;
        RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
-       struct ast_json *variable_list = NULL;
 
        if (!cap) {
                ast_ari_response_alloc_failed(response);
@@ -751,8 +743,17 @@ void ast_ari_channels_originate(struct ast_variable *headers,
 
        /* Parse any query parameters out of the body parameter */
        if (args->variables) {
+               struct ast_json *json_variables;
+
                ast_ari_channels_originate_parse_body(args->variables, args);
-               variable_list = ast_json_object_get(args->variables, "variables");
+               json_variables = ast_json_object_get(args->variables, "variables");
+               if (json_variables) {
+                       if (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;
+                       }
+               }
        }
 
        if (ast_strlen_zero(args->endpoint)) {
@@ -804,13 +805,13 @@ void ast_ari_channels_originate(struct ast_variable *headers,
                }
 
                /* originate a channel, putting it into an application */
-               if (ast_pbx_outgoing_app(dialtech, cap, dialdevice, timeout, app, ast_str_buffer(appdata), NULL, 0, cid_num, cid_name, NULL, NULL, &chan)) {
+               if (ast_pbx_outgoing_app(dialtech, cap, dialdevice, timeout, app, ast_str_buffer(appdata), NULL, 0, cid_num, cid_name, variables, NULL, &chan)) {
                        ast_ari_response_alloc_failed(response);
                        return;
                }
        } else if (!ast_strlen_zero(args->extension)) {
                /* originate a channel, sending it to an extension */
-               if (ast_pbx_outgoing_exten(dialtech, cap, dialdevice, timeout, S_OR(args->context, "default"), args->extension, args->priority ? args->priority : 1, NULL, 0, cid_num, cid_name, NULL, NULL, &chan, 0)) {
+               if (ast_pbx_outgoing_exten(dialtech, cap, dialdevice, timeout, S_OR(args->context, "default"), args->extension, args->priority ? args->priority : 1, NULL, 0, cid_num, cid_name, variables, NULL, &chan, 0)) {
                        ast_ari_response_alloc_failed(response);
                        return;
                }
@@ -820,11 +821,6 @@ void ast_ari_channels_originate(struct ast_variable *headers,
                return;
        }
 
-       if (ari_channels_set_channel_vars(chan, variable_list, response)) {
-               /* response filled in by called function */
-               return;
-       }
-
        snapshot = ast_channel_snapshot_create(chan);
        ast_channel_unlock(chan);