diff options
-rw-r--r-- | apps/app_dial.c | 8 | ||||
-rw-r--r-- | include/asterisk/pbx.h | 31 | ||||
-rw-r--r-- | main/pbx.c | 49 |
3 files changed, 64 insertions, 24 deletions
diff --git a/apps/app_dial.c b/apps/app_dial.c index 0021015bd..fd815b644 100644 --- a/apps/app_dial.c +++ b/apps/app_dial.c @@ -1833,7 +1833,11 @@ static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags if (gosub_args) { res = pbx_exec(peer, theapp, gosub_args); if (!res) { - ast_pbx_run(peer); + struct ast_pbx_args args; + /* A struct initializer fails to compile for this case ... */ + memset(&args, 0, sizeof(args)); + args.no_hangup_chan = 1; + ast_pbx_run_args(peer, &args); } ast_free(gosub_args); if (option_debug) @@ -2154,7 +2158,7 @@ static int load_module(void) if (!con) ast_log(LOG_ERROR, "Dial virtual context 'app_dial_gosub_virtual_context' does not exist and unable to create\n"); else - ast_add_extension2(con, 1, "s", 1, NULL, NULL, "KeepAlive", ast_strdup(""), ast_free_ptr, "app_dial"); + ast_add_extension2(con, 1, "s", 1, NULL, NULL, "NoOp", ast_strdup(""), ast_free_ptr, "app_dial"); res = ast_register_application(app, dial_exec, synopsis, descrip); res |= ast_register_application(rapp, retrydial_exec, rsynopsis, rdescrip); diff --git a/include/asterisk/pbx.h b/include/asterisk/pbx.h index 546356154..37e6f42e5 100644 --- a/include/asterisk/pbx.h +++ b/include/asterisk/pbx.h @@ -260,6 +260,37 @@ enum ast_pbx_result ast_pbx_start(struct ast_channel *c); */ enum ast_pbx_result ast_pbx_run(struct ast_channel *c); +/*! + * \brief Options for ast_pbx_run() + */ +struct ast_pbx_args { + union { + /*! Pad this out so that we have plenty of room to add options + * but still maintain ABI compatibility over time. */ + uint64_t __padding; + struct { + /*! Do not hangup the channel when the PBX is complete. */ + unsigned int no_hangup_chan:1; + }; + }; +}; + +/*! + * \brief Execute the PBX in the current thread + * + * \param c channel to run the pbx on + * \param args options for the pbx + * + * This executes the PBX on a given channel. It allocates a new + * PBX structure for the channel, and provides all PBX functionality. + * See ast_pbx_start for an asynchronous function to run the PBX in a + * new thread as opposed to the current one. + * + * \retval Zero on success + * \retval non-zero on failure + */ +enum ast_pbx_result ast_pbx_run_args(struct ast_channel *c, struct ast_pbx_args *args); + /*! * \brief Add and extension to an extension context. * diff --git a/main/pbx.c b/main/pbx.c index d41000ba4..62158dfe5 100644 --- a/main/pbx.c +++ b/main/pbx.c @@ -302,7 +302,6 @@ static int pbx_builtin_hangup(struct ast_channel *, void *); static int pbx_builtin_background(struct ast_channel *, void *); static int pbx_builtin_wait(struct ast_channel *, void *); static int pbx_builtin_waitexten(struct ast_channel *, void *); -static int pbx_builtin_keepalive(struct ast_channel *, void *); static int pbx_builtin_resetcdr(struct ast_channel *, void *); static int pbx_builtin_setamaflags(struct ast_channel *, void *); static int pbx_builtin_ringing(struct ast_channel *, void *); @@ -711,13 +710,6 @@ static struct pbx_builtin { " Optionally, specify the class for music on hold within parenthesis.\n" "See Also: Playback(application), Background(application).\n" }, - - { "KeepAlive", pbx_builtin_keepalive, - "returns AST_PBX_KEEPALIVE value", - " KeepAlive(): This application is chiefly meant for internal use with Gosubs.\n" - "Please do not run it alone from the dialplan!\n" - }, - }; static struct ast_context *contexts; @@ -3643,7 +3635,8 @@ static int collect_digits(struct ast_channel *c, int waittime, char *buf, int bu return 0; } -static int __ast_pbx_run(struct ast_channel *c) +static enum ast_pbx_result __ast_pbx_run(struct ast_channel *c, + struct ast_pbx_args *args) { int found = 0; /* set if we find at least one match */ int res = 0; @@ -3840,11 +3833,18 @@ static int __ast_pbx_run(struct ast_channel *c) } } } - if (!found && !error) + + if (!found && !error) { ast_log(LOG_WARNING, "Don't know what to do with '%s'\n", c->name); - if (res != AST_PBX_KEEPALIVE) + } + + if (!args || !args->no_hangup_chan) { ast_softhangup(c, c->hangupcause ? c->hangupcause : AST_CAUSE_NORMAL_CLEARING); - if ((res != AST_PBX_KEEPALIVE) && !ast_test_flag(c, AST_FLAG_BRIDGE_HANGUP_RUN) && ast_exists_extension(c, c->context, "h", 1, c->cid.cid_num)) { + } + + if ((!args || !args->no_hangup_chan) && + !ast_test_flag(c, AST_FLAG_BRIDGE_HANGUP_RUN) && + ast_exists_extension(c, c->context, "h", 1, c->cid.cid_num)) { set_ext_pri(c, "h", 1); while ((res = ast_spawn_extension(c, c->context, c->exten, c->priority, c->cid.cid_num, &found, 1)) == 0) { c->priority++; @@ -3859,8 +3859,11 @@ static int __ast_pbx_run(struct ast_channel *c) ast_clear_flag(c, AST_FLAG_BRIDGE_HANGUP_RUN); /* from one round to the next, make sure this gets cleared */ pbx_destroy(c->pbx); c->pbx = NULL; - if (res != AST_PBX_KEEPALIVE) + + if (!args || !args->no_hangup_chan) { ast_hangup(c); + } + return 0; } @@ -3950,7 +3953,7 @@ static void *pbx_thread(void *data) */ struct ast_channel *c = data; - __ast_pbx_run(c); + __ast_pbx_run(c, NULL); decrease_call_count(); pthread_exit(NULL); @@ -3980,19 +3983,26 @@ enum ast_pbx_result ast_pbx_start(struct ast_channel *c) return AST_PBX_SUCCESS; } -enum ast_pbx_result ast_pbx_run(struct ast_channel *c) +enum ast_pbx_result ast_pbx_run_args(struct ast_channel *c, struct ast_pbx_args *args) { enum ast_pbx_result res = AST_PBX_SUCCESS; - if (increase_call_count(c)) + if (increase_call_count(c)) { return AST_PBX_CALL_LIMIT; + } + + res = __ast_pbx_run(c, args); - res = __ast_pbx_run(c); decrease_call_count(); return res; } +enum ast_pbx_result ast_pbx_run(struct ast_channel *c) +{ + return ast_pbx_run_args(c, NULL); +} + int ast_active_calls(void) { return countcalls; @@ -7565,11 +7575,6 @@ static int pbx_builtin_answer(struct ast_channel *chan, void *data) return __ast_answer(chan, delay); } -static int pbx_builtin_keepalive(struct ast_channel *chan, void *data) -{ - return AST_PBX_KEEPALIVE; -} - AST_APP_OPTIONS(resetcdr_opts, { AST_APP_OPTION('w', AST_CDR_FLAG_POSTED), AST_APP_OPTION('a', AST_CDR_FLAG_LOCKED), |