From 7f836c1c15ce521bf01ab86db27fdfc84967e615 Mon Sep 17 00:00:00 2001 From: Mark Michelson Date: Wed, 7 Jan 2015 18:54:06 +0000 Subject: [PATCH] Add the ability to continue and originate using priority labels. With this patch, the following two ARI commands POST /channels POST /channels/{id}/continue Accept a new parameter, label, that can be used to continue to or originate to a priority label in the dialplan. Because this is adding a new parameter to ARI commands, the API version of ARI has been bumped from 1.6.0 to 1.7.0. This patch comes courtesy of Nir Simionovich from Greenfield Tech. Thanks! ASTERISK-24412 #close Reported by Nir Simionovich Review: https://reviewboard.asterisk.org/r/4285 ........ Merged revisions 430337 from http://svn.asterisk.org/svn/asterisk/branches/13 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@430338 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- CHANGES | 5 ++ res/ari/resource_channels.c | 87 +++++++++++++++++++++++++++++++-- res/ari/resource_channels.h | 6 +++ res/res_ari_channels.c | 21 ++++++++ rest-api/api-docs/channels.json | 24 +++++++++ rest-api/resources.json | 2 +- 6 files changed, 141 insertions(+), 4 deletions(-) diff --git a/CHANGES b/CHANGES index 05c2f60537..5f6a50e4a5 100644 --- a/CHANGES +++ b/CHANGES @@ -128,6 +128,11 @@ ARI * "language" (the default spoken language for the channel) is now included in the standard channel state output for suitable events. + * The POST channels/{id} operation and the POST channels/{id}/continue operation + now have a new "label" parameter. This allows for origination or continuation + to a labeled priority in the dialplan instead of requiring a specific priority + number. The ARI version has been bumped to 1.7.0 as a result. + AMI ------------------ * "Language" (the default spoken language for the channel) is now included in diff --git a/res/ari/resource_channels.c b/res/ari/resource_channels.c index e3ef9eb16e..d1d54a2f04 100644 --- a/res/ari/resource_channels.c +++ b/res/ari/resource_channels.c @@ -91,6 +91,10 @@ void ast_ari_channels_continue_in_dialplan( 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); + int ipri; + const char *context; + const char *exten; ast_assert(response != NULL); @@ -99,7 +103,52 @@ void ast_ari_channels_continue_in_dialplan( return; } - if (stasis_app_control_continue(control, args->context, args->extension, args->priority)) { + snapshot = stasis_app_control_get_snapshot(control); + if (!snapshot) { + return; + } + + if (ast_strlen_zero(args->context)) { + context = snapshot->context; + exten = S_OR(args->extension, snapshot->exten); + } else { + context = args->context; + exten = S_OR(args->extension, "s"); + } + + if (!ast_strlen_zero(args->label)) { + /* A label was provided in the request, use that */ + + if (sscanf(args->label, "%30d", &ipri) != 1) { + ipri = ast_findlabel_extension(NULL, context, exten, args->label, NULL); + if (ipri == -1) { + ast_log(AST_LOG_ERROR, "Requested label: %s can not be found in context: %s\n", args->label, context); + ast_ari_response_error(response, 404, "Not Found", "Requested label can not be found"); + return; + } + } else { + ast_debug(3, "Numeric value provided for label, jumping to that priority\n"); + } + + if (ipri == 0) { + ast_log(AST_LOG_ERROR, "Invalid priority label '%s' specified for extension %s in context: %s\n", + args->label, exten, context); + ast_ari_response_error(response, 400, "Bad Request", "Requested priority is illegal"); + return; + } + + } else if (args->priority) { + /* No label provided, use provided priority */ + ipri = args->priority; + } else if (ast_strlen_zero(args->context) && ast_strlen_zero(args->extension)) { + /* Special case. No exten, context, or priority provided, then move on to the next priority */ + ipri = snapshot->priority + 1; + } else { + ipri = 1; + } + + + if (stasis_app_control_continue(control, context, exten, ipri)) { ast_ari_response_alloc_failed(response); return; } @@ -791,6 +840,7 @@ static void ari_channels_handle_originate_with_id(const char *args_endpoint, const char *args_extension, const char *args_context, long args_priority, + const char *args_label, const char *args_app, const char *args_app_args, const char *args_caller_id, @@ -811,7 +861,7 @@ static void ari_channels_handle_originate_with_id(const char *args_endpoint, ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT), ao2_cleanup); char *stuff; struct ast_channel *other = NULL; - struct ast_channel *chan; + struct ast_channel *chan = NULL; RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup); struct ast_assigned_ids assignedids = { .uniqueid = args_channel_id, @@ -880,7 +930,36 @@ static void ari_channels_handle_originate_with_id(const char *args_endpoint, ast_copy_string(origination->context, S_OR(args_context, "default"), sizeof(origination->context)); ast_copy_string(origination->exten, args_extension, sizeof(origination->exten)); - origination->priority = args_priority ? args_priority : 1; + + if (!ast_strlen_zero(args_label)) { + /* A label was provided in the request, use that */ + int ipri = 1; + if (sscanf(args_label, "%30d", &ipri) != 1) { + ipri = ast_findlabel_extension(chan, origination->context, origination->exten, args_label, args_caller_id); + + if (ipri == -1) { + ast_log(AST_LOG_ERROR, "Requested label: %s can not be found in context: %s\n", args_label, args_context); + ast_ari_response_error(response, 404, "Not Found", "Requested label can not be found"); + return; + } + } else { + ast_debug(3, "Numeric value provided for label, jumping to that priority\n"); + } + + if (ipri == 0) { + ast_log(AST_LOG_ERROR, "Invalid priority label '%s' specified for extension %s in context: %s\n", + args_label, args_extension, args_context); + ast_ari_response_error(response, 400, "Bad Request", "Requested priority is illegal"); + return; + } + + /* Our priority was provided by a label */ + origination->priority = ipri; + } else { + /* No label provided, use provided priority */ + origination->priority = args_priority ? args_priority : 1; + } + origination->appdata[0] = '\0'; } else { ast_ari_response_error(response, 400, "Bad Request", @@ -1042,6 +1121,7 @@ void ast_ari_channels_originate_with_id(struct ast_variable *headers, args->extension, args->context, args->priority, + args->label, args->app, args->app_args, args->caller_id, @@ -1079,6 +1159,7 @@ void ast_ari_channels_originate(struct ast_variable *headers, args->extension, args->context, args->priority, + args->label, args->app, args->app_args, args->caller_id, diff --git a/res/ari/resource_channels.h b/res/ari/resource_channels.h index 627f9c97ae..dddfcf3a92 100644 --- a/res/ari/resource_channels.h +++ b/res/ari/resource_channels.h @@ -60,6 +60,8 @@ struct ast_ari_channels_originate_args { const char *context; /*! The priority to dial after the endpoint answers. If omitted, uses 1 */ long priority; + /*! The label to dial after the endpoint answers. Will supersede 'priority' if provided. */ + const char *label; /*! The application that is subscribed to the originated channel, and passed to the Stasis application. */ const char *app; /*! The application arguments to pass to the Stasis application. */ @@ -123,6 +125,8 @@ struct ast_ari_channels_originate_with_id_args { const char *context; /*! The priority to dial after the endpoint answers. If omitted, uses 1 */ long priority; + /*! The label to dial after the endpoint answers. Will supersede priority, if provided */ + const char *label; /*! The application that is subscribed to the originated channel, and passed to the Stasis application. */ const char *app; /*! The application arguments to pass to the Stasis application. */ @@ -195,6 +199,8 @@ struct ast_ari_channels_continue_in_dialplan_args { const char *extension; /*! The priority to continue to. */ int priority; + /*! The label to continue to - will supersede 'priority' if both are provided. */ + const char *label; }; /*! * \brief Body parsing function for /channels/{channelId}/continue. diff --git a/res/res_ari_channels.c b/res/res_ari_channels.c index 8cc25f1d87..82bb662d27 100644 --- a/res/res_ari_channels.c +++ b/res/res_ari_channels.c @@ -124,6 +124,10 @@ int ast_ari_channels_originate_parse_body( if (field) { args->priority = ast_json_integer_get(field); } + field = ast_json_object_get(body, "label"); + if (field) { + args->label = ast_json_string_get(field); + } field = ast_json_object_get(body, "app"); if (field) { args->app = ast_json_string_get(field); @@ -188,6 +192,9 @@ static void ast_ari_channels_originate_cb( if (strcmp(i->name, "priority") == 0) { args.priority = atol(i->value); } else + if (strcmp(i->name, "label") == 0) { + args.label = (i->value); + } else if (strcmp(i->name, "app") == 0) { args.app = (i->value); } else @@ -341,6 +348,10 @@ int ast_ari_channels_originate_with_id_parse_body( if (field) { args->priority = ast_json_integer_get(field); } + field = ast_json_object_get(body, "label"); + if (field) { + args->label = ast_json_string_get(field); + } field = ast_json_object_get(body, "app"); if (field) { args->app = ast_json_string_get(field); @@ -401,6 +412,9 @@ static void ast_ari_channels_originate_with_id_cb( if (strcmp(i->name, "priority") == 0) { args.priority = atol(i->value); } else + if (strcmp(i->name, "label") == 0) { + args.label = (i->value); + } else if (strcmp(i->name, "app") == 0) { args.app = (i->value); } else @@ -592,6 +606,10 @@ int ast_ari_channels_continue_in_dialplan_parse_body( if (field) { args->priority = ast_json_integer_get(field); } + field = ast_json_object_get(body, "label"); + if (field) { + args->label = ast_json_string_get(field); + } return 0; } @@ -625,6 +643,9 @@ static void ast_ari_channels_continue_in_dialplan_cb( if (strcmp(i->name, "priority") == 0) { args.priority = atoi(i->value); } else + if (strcmp(i->name, "label") == 0) { + args.label = (i->value); + } else {} } for (i = path_vars; i; i = i->next) { diff --git a/rest-api/api-docs/channels.json b/rest-api/api-docs/channels.json index cd309db109..87dee7c84e 100644 --- a/rest-api/api-docs/channels.json +++ b/rest-api/api-docs/channels.json @@ -56,6 +56,14 @@ "allowMultiple": false, "dataType": "long" }, + { + "name": "label", + "description": "The label to dial after the endpoint answers. Will supersede 'priority' if provided.", + "paramType": "query", + "required": false, + "allowMultiple": false, + "dataType": "string" + }, { "name": "app", "description": "The application that is subscribed to the originated channel, and passed to the Stasis application.", @@ -204,6 +212,14 @@ "allowMultiple": false, "dataType": "long" }, + { + "name": "label", + "description": "The label to dial after the endpoint answers. Will supersede priority, if provided", + "paramType": "query", + "required": false, + "allowMultiple": false, + "dataType": "string" + }, { "name": "app", "description": "The application that is subscribed to the originated channel, and passed to the Stasis application.", @@ -356,6 +372,14 @@ "required": false, "allowMultiple": false, "dataType": "int" + }, + { + "name": "label", + "description": "The label to continue to - will supersede 'priority' if both are provided.", + "paramType": "query", + "required": false, + "allowMultiple": false, + "dataType": "string" } ], "errorResponses": [ diff --git a/rest-api/resources.json b/rest-api/resources.json index 2cc039dc3a..4a098f51f0 100644 --- a/rest-api/resources.json +++ b/rest-api/resources.json @@ -2,7 +2,7 @@ "_copyright": "Copyright (C) 2012 - 2013, Digium, Inc.", "_author": "David M. Lee, II ", "_svn_revision": "$Revision$", - "apiVersion": "1.6.0", + "apiVersion": "1.7.0", "swaggerVersion": "1.1", "basePath": "http://localhost:8088/ari", "apis": [