summaryrefslogtreecommitdiff
path: root/apps/app_page.c
diff options
context:
space:
mode:
authorRichard Mudgett <rmudgett@digium.com>2015-09-22 17:08:49 -0500
committerRichard Mudgett <rmudgett@digium.com>2015-09-22 17:32:03 -0500
commit06f4f80a63092845a3e86fc827b025854beaf4b4 (patch)
treea2d1eb404f4823d509102daa3ab2cdce235bbafc /apps/app_page.c
parent069813db3c5f9fdd3d0c15c8237738c5bbf6d42a (diff)
app_page.c: Fix crash when forwarding with a predial handler.
Page uses the async method of dialing with the dial API. When a call gets forwarded there is no calling channel available. If the predial handler was set then the calling channel could not be put into auto-service for the forwarded call because it doesn't exist. A crash is the result. * Moved the callee predial parameter string processing to before the string is passed to the dial API rather than having the dial API do it. There are a few benefits do doing this. The first is the predial parameter string processing doesn't need to be done for each channel called by the dial API. The second is in async mode and the forwarded channel is to have the predial handler executed on it then the non-existent calling channel does not need to be present to process the predial parameter string. * Don't start auto-service on a non-existent calling channel to execute the predial handler when the dial API is in async mode and forwarding a call. ASTERISK-25384 #close Reported by: Chet Stevens Change-Id: If53892b286d29f6cf955e2545b03dcffa2610981
Diffstat (limited to 'apps/app_page.c')
-rw-r--r--apps/app_page.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/apps/app_page.c b/apps/app_page.c
index cea75cb5e..10a96b61b 100644
--- a/apps/app_page.c
+++ b/apps/app_page.c
@@ -249,12 +249,18 @@ static void page_state_callback(struct ast_dial *dial)
static int page_exec(struct ast_channel *chan, const char *data)
{
- char *tech, *resource, *tmp;
- char confbridgeopts[128], originator[AST_CHANNEL_NAME];
+ char *tech;
+ char *resource;
+ char *tmp;
+ char *predial_callee = NULL;
+ char confbridgeopts[128];
+ char originator[AST_CHANNEL_NAME];
struct page_options options = { { 0, }, { 0, } };
unsigned int confid = ast_random();
struct ast_app *app;
- int res = 0, pos = 0, i = 0;
+ int res = 0;
+ int pos = 0;
+ int i = 0;
struct ast_dial **dial_list;
unsigned int num_dials;
int timeout = 0;
@@ -310,6 +316,15 @@ static int page_exec(struct ast_channel *chan, const char *data)
return -1;
}
+ /* PREDIAL: Preprocess any callee gosub arguments. */
+ if (ast_test_flag(&options.flags, PAGE_PREDIAL_CALLEE)
+ && !ast_strlen_zero(options.opts[OPT_ARG_PREDIAL_CALLEE])) {
+ ast_replace_subargument_delimiter(options.opts[OPT_ARG_PREDIAL_CALLEE]);
+ predial_callee =
+ (char *) ast_app_expand_sub_args(chan, options.opts[OPT_ARG_PREDIAL_CALLEE]);
+ }
+
+ /* PREDIAL: Run gosub on the caller's channel */
if (ast_test_flag(&options.flags, PAGE_PREDIAL_CALLER)
&& !ast_strlen_zero(options.opts[OPT_ARG_PREDIAL_CALLER])) {
ast_replace_subargument_delimiter(options.opts[OPT_ARG_PREDIAL_CALLER]);
@@ -360,9 +375,8 @@ static int page_exec(struct ast_channel *chan, const char *data)
/* Set ANSWER_EXEC as global option */
ast_dial_option_global_enable(dial, AST_DIAL_OPTION_ANSWER_EXEC, confbridgeopts);
- if (ast_test_flag(&options.flags, PAGE_PREDIAL_CALLEE)
- && !ast_strlen_zero(options.opts[OPT_ARG_PREDIAL_CALLEE])) {
- ast_dial_option_global_enable(dial, AST_DIAL_OPTION_PREDIAL, options.opts[OPT_ARG_PREDIAL_CALLEE]);
+ if (predial_callee) {
+ ast_dial_option_global_enable(dial, AST_DIAL_OPTION_PREDIAL, predial_callee);
}
if (timeout) {
@@ -383,6 +397,8 @@ static int page_exec(struct ast_channel *chan, const char *data)
dial_list[pos++] = dial;
}
+ ast_free(predial_callee);
+
if (!ast_test_flag(&options.flags, PAGE_QUIET)) {
res = ast_streamfile(chan, "beep", ast_channel_language(chan));
if (!res)