diff --git a/include/asterisk/stasis_app.h b/include/asterisk/stasis_app.h index 3eed47e35c..881ef72a49 100644 --- a/include/asterisk/stasis_app.h +++ b/include/asterisk/stasis_app.h @@ -142,8 +142,14 @@ const char *stasis_app_control_get_channel_id( * If the channel is no longer in \c res_stasis, this function does nothing. * * \param control Control for \c res_stasis + * \param context An optional context to continue to + * \param extension An optional extension to continue to + * \param priority An optional priority to continue to + * + * \return 0 for success + * \return -1 for error. */ -void stasis_app_control_continue(struct stasis_app_control *control); +int stasis_app_control_continue(struct stasis_app_control *control, const char *context, const char *extension, int priority); /*! * \brief Answer the channel associated with this control. diff --git a/res/res_stasis_http_channels.c b/res/res_stasis_http_channels.c index 87f663d946..2776b167ed 100644 --- a/res/res_stasis_http_channels.c +++ b/res/res_stasis_http_channels.c @@ -191,6 +191,18 @@ static void stasis_http_continue_in_dialplan_cb( struct ast_continue_in_dialplan_args args = {}; struct ast_variable *i; + for (i = get_params; i; i = i->next) { + if (strcmp(i->name, "context") == 0) { + args.context = (i->value); + } else + if (strcmp(i->name, "extension") == 0) { + args.extension = (i->value); + } else + if (strcmp(i->name, "priority") == 0) { + args.priority = atoi(i->value); + } else + {} + } for (i = path_vars; i; i = i->next) { if (strcmp(i->name, "channelId") == 0) { args.channel_id = (i->value); diff --git a/res/stasis/control.c b/res/stasis/control.c index 06f36728fc..310b66cbc7 100644 --- a/res/stasis/control.c +++ b/res/stasis/control.c @@ -33,6 +33,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "control.h" #include "asterisk/bridging.h" #include "asterisk/bridging_features.h" +#include "asterisk/pbx.h" struct stasis_app_control { /*! Queue of commands to dispatch on the channel */ @@ -91,17 +92,43 @@ int control_is_done(struct stasis_app_control *control) return control->is_done; } +struct stasis_app_control_continue_data { + char context[AST_MAX_CONTEXT]; + char extension[AST_MAX_EXTENSION]; + int priority; +}; + static void *app_control_continue(struct stasis_app_control *control, struct ast_channel *chan, void *data) { + RAII_VAR(struct stasis_app_control_continue_data *, continue_data, data, ast_free); + /* Called from stasis_app_exec thread; no lock needed */ + ast_explicit_goto(control->channel, continue_data->context, continue_data->extension, continue_data->priority); + control->is_done = 1; + return NULL; } -void stasis_app_control_continue(struct stasis_app_control *control) +int stasis_app_control_continue(struct stasis_app_control *control, const char *context, const char *extension, int priority) { - stasis_app_send_command_async(control, app_control_continue, NULL); + struct stasis_app_control_continue_data *continue_data; + + if (!(continue_data = ast_calloc(1, sizeof(*continue_data)))) { + return -1; + } + ast_copy_string(continue_data->context, S_OR(context, ""), sizeof(continue_data->context)); + ast_copy_string(continue_data->extension, S_OR(extension, ""), sizeof(continue_data->extension)); + if (priority > 0) { + continue_data->priority = priority; + } else { + continue_data->priority = -1; + } + + stasis_app_send_command_async(control, app_control_continue, continue_data); + + return 0; } struct ast_channel_snapshot *stasis_app_control_get_snapshot( diff --git a/res/stasis_http/resource_channels.c b/res/stasis_http/resource_channels.c index c51696a287..4d2ebdfbd8 100644 --- a/res/stasis_http/resource_channels.c +++ b/res/stasis_http/resource_channels.c @@ -97,7 +97,11 @@ void stasis_http_continue_in_dialplan( return; } - stasis_app_control_continue(control); + if (stasis_app_control_continue(control, args->context, args->extension, args->priority)) { + stasis_http_response_alloc_failed(response); + return; + } + stasis_http_response_no_content(response); } diff --git a/res/stasis_http/resource_channels.h b/res/stasis_http/resource_channels.h index 4616611e63..1cb408b4ac 100644 --- a/res/stasis_http/resource_channels.h +++ b/res/stasis_http/resource_channels.h @@ -124,6 +124,12 @@ void stasis_http_dial(struct ast_variable *headers, struct ast_dial_args *args, struct ast_continue_in_dialplan_args { /*! \brief Channel's id */ const char *channel_id; + /*! \brief The context to continue to. */ + const char *context; + /*! \brief The extension to continue to. */ + const char *extension; + /*! \brief The priority to continue to. */ + int priority; }; /*! * \brief Exit application; continue execution in the dialplan. diff --git a/rest-api/api-docs/channels.json b/rest-api/api-docs/channels.json index 4b35f155ed..d097267e7d 100644 --- a/rest-api/api-docs/channels.json +++ b/rest-api/api-docs/channels.json @@ -207,6 +207,30 @@ "required": true, "allowMultiple": false, "dataType": "string" + }, + { + "name": "context", + "description": "The context to continue to.", + "paramType": "query", + "required": false, + "allowMultiple": false, + "dataType": "string" + }, + { + "name": "extension", + "description": "The extension to continue to.", + "paramType": "query", + "required": false, + "allowMultiple": false, + "dataType": "string" + }, + { + "name": "priority", + "description": "The priority to continue to.", + "paramType": "query", + "required": false, + "allowMultiple": false, + "dataType": "int" } ], "errorResponses": [