summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
Diffstat (limited to 'main')
-rw-r--r--main/app.c109
-rw-r--r--main/ccss.c4
-rw-r--r--main/channel.c6
3 files changed, 45 insertions, 74 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;
}
diff --git a/main/ccss.c b/main/ccss.c
index fe748e98c..b27823aaa 100644
--- a/main/ccss.c
+++ b/main/ccss.c
@@ -2724,7 +2724,7 @@ static void *generic_recall(void *data)
if (!ast_strlen_zero(callback_macro)) {
ast_log_dynamic_level(cc_logger_level, "Core %d: There's a callback macro configured for agent %s\n",
agent->core_id, agent->device_name);
- if (ast_app_run_macro(NULL, chan, callback_macro, NULL)) {
+ if (ast_app_exec_macro(NULL, chan, callback_macro)) {
ast_cc_failed(agent->core_id, "Callback macro to %s failed. Maybe a hangup?", agent->device_name);
ast_hangup(chan);
return NULL;
@@ -2734,7 +2734,7 @@ static void *generic_recall(void *data)
if (!ast_strlen_zero(callback_sub)) {
ast_log_dynamic_level(cc_logger_level, "Core %d: There's a callback subroutine configured for agent %s\n",
agent->core_id, agent->device_name);
- if (ast_app_run_sub(NULL, chan, callback_sub, NULL)) {
+ if (ast_app_exec_sub(NULL, chan, callback_sub, 0)) {
ast_cc_failed(agent->core_id, "Callback subroutine to %s failed. Maybe a hangup?", agent->device_name);
ast_hangup(chan);
return NULL;
diff --git a/main/channel.c b/main/channel.c
index 6b3621dae..b9fc0b5d8 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -5729,7 +5729,7 @@ int ast_pre_call(struct ast_channel *chan, const char *sub_args)
return res;
}
ast_channel_unlock(chan);
- return ast_app_exec_sub(NULL, chan, sub_args);
+ return ast_app_exec_sub(NULL, chan, sub_args, 0);
}
int ast_call(struct ast_channel *chan, const char *addr, int timeout)
@@ -9801,7 +9801,7 @@ int ast_channel_connected_line_sub(struct ast_channel *autoservice_chan, struct
}
ast_channel_unlock(sub_chan);
- retval = ast_app_run_sub(autoservice_chan, sub_chan, sub, sub_args);
+ retval = ast_app_run_sub(autoservice_chan, sub_chan, sub, sub_args, 0);
if (!retval) {
struct ast_party_connected_line saved_connected;
@@ -9844,7 +9844,7 @@ int ast_channel_redirecting_sub(struct ast_channel *autoservice_chan, struct ast
}
ast_channel_unlock(sub_chan);
- retval = ast_app_run_sub(autoservice_chan, sub_chan, sub, sub_args);
+ retval = ast_app_run_sub(autoservice_chan, sub_chan, sub, sub_args, 0);
if (!retval) {
struct ast_party_redirecting saved_redirecting;