diff options
Diffstat (limited to 'main/app.c')
-rw-r--r-- | main/app.c | 109 |
1 files changed, 40 insertions, 69 deletions
diff --git a/main/app.c b/main/app.c index 8cc22c6c7..210ef1168 100644 --- a/main/app.c +++ b/main/app.c @@ -55,6 +55,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/linkedlists.h" #include "asterisk/threadstorage.h" #include "asterisk/test.h" +#include "asterisk/module.h" AST_THREADSTORAGE_PUBLIC(ast_str_thread_global_buf); @@ -312,82 +313,52 @@ int ast_app_run_macro(struct ast_channel *autoservice_chan, struct ast_channel * return res; } -int ast_app_exec_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const char *sub_args) +static const struct ast_app_stack_funcs *app_stack_callbacks; + +void ast_install_stack_functions(const struct ast_app_stack_funcs *funcs) { - struct ast_app *sub_app; - const char *saved_context; - const char *saved_exten; - int saved_priority; - int saved_autoloopflag; - int res; + app_stack_callbacks = funcs; +} + +const char *ast_app_expand_sub_args(struct ast_channel *chan, const char *args) +{ + const struct ast_app_stack_funcs *funcs; + const char *new_args; - sub_app = pbx_findapp("Gosub"); - if (!sub_app) { + funcs = app_stack_callbacks; + if (!funcs || !funcs->expand_sub_args) { ast_log(LOG_WARNING, - "Cannot run 'Gosub(%s)'. The application is not available.\n", sub_args); - return -1; - } - if (autoservice_chan) { - ast_autoservice_start(autoservice_chan); + "Cannot expand 'Gosub(%s)' arguments. The app_stack module is not available.\n", + args); + return NULL; } + ast_module_ref(funcs->module); - ast_channel_lock(sub_chan); - - /* Save current dialplan location */ - saved_context = ast_strdupa(ast_channel_context(sub_chan)); - saved_exten = ast_strdupa(ast_channel_exten(sub_chan)); - saved_priority = ast_channel_priority(sub_chan); - - /* - * Save flag to restore at the end so we don't have to play with - * the priority in the gosub location string. - */ - saved_autoloopflag = ast_test_flag(ast_channel_flags(sub_chan), AST_FLAG_IN_AUTOLOOP); - ast_clear_flag(ast_channel_flags(sub_chan), AST_FLAG_IN_AUTOLOOP); - - /* Set known location for Gosub to return - 1 */ - ast_channel_context_set(sub_chan, "gosub_virtual_context"); - ast_channel_exten_set(sub_chan, "s"); - ast_channel_priority_set(sub_chan, 1 - 1); - - ast_debug(4, "%s Original location: %s,%s,%d\n", ast_channel_name(sub_chan), - saved_context, saved_exten, saved_priority); - - ast_channel_unlock(sub_chan); - res = pbx_exec(sub_chan, sub_app, sub_args); - ast_debug(4, "Gosub exited with status %d\n", res); - ast_channel_lock(sub_chan); - if (!res) { - struct ast_pbx_args gosub_args = {{0}}; - struct ast_pbx *saved_pbx; - - /* supress warning about a pbx already being on the channel */ - saved_pbx = ast_channel_pbx(sub_chan); - ast_channel_pbx_set(sub_chan, NULL); + new_args = funcs->expand_sub_args(chan, args); + ast_module_unref(funcs->module); + return new_args; +} - ast_channel_unlock(sub_chan); - gosub_args.no_hangup_chan = 1; - ast_pbx_run_args(sub_chan, &gosub_args); - ast_channel_lock(sub_chan); +int ast_app_exec_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const char *sub_args, int ignore_hangup) +{ + const struct ast_app_stack_funcs *funcs; + int res; - /* Restore pbx. */ - ast_free(ast_channel_pbx(sub_chan)); - ast_channel_pbx_set(sub_chan, saved_pbx); + funcs = app_stack_callbacks; + if (!funcs || !funcs->run_sub) { + ast_log(LOG_WARNING, + "Cannot run 'Gosub(%s)'. The app_stack module is not available.\n", + sub_args); + return -1; } + ast_module_ref(funcs->module); - ast_debug(4, "%s Ending location: %s,%s,%d\n", ast_channel_name(sub_chan), - ast_channel_context(sub_chan), ast_channel_exten(sub_chan), - ast_channel_priority(sub_chan)); - - /* Restore flag */ - ast_set2_flag(ast_channel_flags(sub_chan), saved_autoloopflag, AST_FLAG_IN_AUTOLOOP); - - /* Restore dialplan location */ - ast_channel_context_set(sub_chan, saved_context); - ast_channel_exten_set(sub_chan, saved_exten); - ast_channel_priority_set(sub_chan, saved_priority); + if (autoservice_chan) { + ast_autoservice_start(autoservice_chan); + } - ast_channel_unlock(sub_chan); + res = funcs->run_sub(sub_chan, sub_args, ignore_hangup); + ast_module_unref(funcs->module); if (autoservice_chan) { ast_autoservice_stop(autoservice_chan); @@ -395,14 +366,14 @@ int ast_app_exec_sub(struct ast_channel *autoservice_chan, struct ast_channel *s return res; } -int ast_app_run_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const char *sub_location, const char *sub_args) +int ast_app_run_sub(struct ast_channel *autoservice_chan, struct ast_channel *sub_chan, const char *sub_location, const char *sub_args, int ignore_hangup) { int res; char *args_str; size_t args_len; if (ast_strlen_zero(sub_args)) { - return ast_app_exec_sub(autoservice_chan, sub_chan, sub_location); + return ast_app_exec_sub(autoservice_chan, sub_chan, sub_location, ignore_hangup); } /* Create the Gosub application argument string. */ @@ -413,7 +384,7 @@ int ast_app_run_sub(struct ast_channel *autoservice_chan, struct ast_channel *su } snprintf(args_str, args_len, "%s(%s)", sub_location, sub_args); - res = ast_app_exec_sub(autoservice_chan, sub_chan, args_str); + res = ast_app_exec_sub(autoservice_chan, sub_chan, args_str, ignore_hangup); ast_free(args_str); return res; } |