summaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorRichard Mudgett <rmudgett@digium.com>2012-04-23 17:05:55 +0000
committerRichard Mudgett <rmudgett@digium.com>2012-04-23 17:05:55 +0000
commitf663924517e9380f74c2e821ff29f973705e8654 (patch)
treefb6c3977fe6cb9b9261f298bcfcf2bef9e4ef6c8 /apps
parentf03d56a84d252330dab075f51db44f4ebb440b48 (diff)
Make app_dial and app_queue use new macro and gosub calls.
* Simplify some code in app_dial and app_queue by calling ast_app_exec_macro() and ast_app_exec_sub(). * Fix minor locking issue in app_dial for post-answer macro/gosub MACRO/GOSUB_RESULT=GOTO: handling. git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@363269 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'apps')
-rw-r--r--apps/app_dial.c176
-rw-r--r--apps/app_queue.c123
2 files changed, 90 insertions, 209 deletions
diff --git a/apps/app_dial.c b/apps/app_dial.c
index 76f3bf36e..875e943e3 100644
--- a/apps/app_dial.c
+++ b/apps/app_dial.c
@@ -2626,40 +2626,26 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
}
if (ast_test_flag64(&opts, OPT_CALLEE_MACRO) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_MACRO])) {
- struct ast_app *theapp;
- const char *macro_result;
+ const char *macro_result_peer;
- res = ast_autoservice_start(chan);
- if (res) {
- ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
- res = -1;
- }
-
- theapp = pbx_findapp("Macro");
-
- if (theapp && !res) { /* XXX why check res here ? */
- /* Set peer->exten and peer->context so that MACRO_EXTEN and MACRO_CONTEXT get set */
- ast_channel_context_set(peer, ast_channel_context(chan));
- ast_channel_exten_set(peer, ast_channel_exten(chan));
-
- ast_replace_subargument_delimiter(opt_args[OPT_ARG_CALLEE_MACRO]);
- res = pbx_exec(peer, theapp, opt_args[OPT_ARG_CALLEE_MACRO]);
- ast_debug(1, "Macro exited with status %d\n", res);
- res = 0;
- } else {
- ast_log(LOG_ERROR, "Could not find application Macro\n");
- res = -1;
- }
+ /* Set peer->exten and peer->context so that MACRO_EXTEN and MACRO_CONTEXT get set */
+ ast_channel_lock_both(chan, peer);
+ ast_channel_context_set(peer, ast_channel_context(chan));
+ ast_channel_exten_set(peer, ast_channel_exten(chan));
+ ast_channel_unlock(peer);
+ ast_channel_unlock(chan);
- if (ast_autoservice_stop(chan) < 0) {
- res = -1;
- }
+ ast_replace_subargument_delimiter(opt_args[OPT_ARG_CALLEE_MACRO]);
+ res = ast_app_exec_macro(chan, peer, opt_args[OPT_ARG_CALLEE_MACRO]);
ast_channel_lock(peer);
- if (!res && (macro_result = pbx_builtin_getvar_helper(peer, "MACRO_RESULT"))) {
+ if (!res && (macro_result_peer = pbx_builtin_getvar_helper(peer, "MACRO_RESULT"))) {
+ char *macro_result = ast_strdupa(macro_result_peer);
char *macro_transfer_dest;
+ ast_channel_unlock(peer);
+
if (!strcasecmp(macro_result, "BUSY")) {
ast_copy_string(pa.status, macro_result, sizeof(pa.status));
ast_set_flag64(peerflags, OPT_GO_ON);
@@ -2678,7 +2664,8 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
} else if (!strcasecmp(macro_result, "ABORT")) {
/* Hangup both ends unless the caller has the g flag */
res = -1;
- } else if (!strncasecmp(macro_result, "GOTO:", 5) && (macro_transfer_dest = ast_strdupa(macro_result + 5))) {
+ } else if (!strncasecmp(macro_result, "GOTO:", 5)) {
+ macro_transfer_dest = macro_result + 5;
res = -1;
/* perform a transfer to a new extension */
if (strchr(macro_transfer_dest, '^')) { /* context^exten^priority*/
@@ -2687,86 +2674,54 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
ast_set_flag64(peerflags, OPT_GO_ON);
}
}
+ } else {
+ ast_channel_unlock(peer);
}
-
- ast_channel_unlock(peer);
}
if (ast_test_flag64(&opts, OPT_CALLEE_GOSUB) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_GOSUB])) {
- struct ast_app *theapp;
- const char *gosub_result;
- char *gosub_args, *gosub_argstart;
+ const char *gosub_result_peer;
+ char *gosub_argstart;
+ char *gosub_args = NULL;
int res9 = -1;
- res9 = ast_autoservice_start(chan);
- if (res9) {
- ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
- res9 = -1;
- }
-
- theapp = pbx_findapp("Gosub");
-
- if (theapp && !res9) {
- ast_replace_subargument_delimiter(opt_args[OPT_ARG_CALLEE_GOSUB]);
-
- /* Set where we came from */
- ast_channel_context_set(peer, "app_dial_gosub_virtual_context");
- ast_channel_exten_set(peer, "s");
- ast_channel_priority_set(peer, 0);
-
- gosub_argstart = strchr(opt_args[OPT_ARG_CALLEE_GOSUB], ',');
- if (gosub_argstart) {
- const char *what_is_s = "s";
- *gosub_argstart = 0;
- if (!ast_exists_extension(peer, opt_args[OPT_ARG_CALLEE_GOSUB], "s", 1, S_COR(ast_channel_caller(peer)->id.number.valid, ast_channel_caller(peer)->id.number.str, NULL)) &&
- ast_exists_extension(peer, opt_args[OPT_ARG_CALLEE_GOSUB], "~~s~~", 1, S_COR(ast_channel_caller(peer)->id.number.valid, ast_channel_caller(peer)->id.number.str, NULL))) {
- what_is_s = "~~s~~";
- }
- if (asprintf(&gosub_args, "%s,%s,1(%s)", opt_args[OPT_ARG_CALLEE_GOSUB], what_is_s, gosub_argstart + 1) < 0) {
- ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
- gosub_args = NULL;
- }
- *gosub_argstart = ',';
- } else {
- const char *what_is_s = "s";
- if (!ast_exists_extension(peer, opt_args[OPT_ARG_CALLEE_GOSUB], "s", 1, S_COR(ast_channel_caller(peer)->id.number.valid, ast_channel_caller(peer)->id.number.str, NULL)) &&
- ast_exists_extension(peer, opt_args[OPT_ARG_CALLEE_GOSUB], "~~s~~", 1, S_COR(ast_channel_caller(peer)->id.number.valid, ast_channel_caller(peer)->id.number.str, NULL))) {
- what_is_s = "~~s~~";
- }
- if (asprintf(&gosub_args, "%s,%s,1", opt_args[OPT_ARG_CALLEE_GOSUB], what_is_s) < 0) {
- ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
- gosub_args = NULL;
- }
+ ast_replace_subargument_delimiter(opt_args[OPT_ARG_CALLEE_GOSUB]);
+ gosub_argstart = strchr(opt_args[OPT_ARG_CALLEE_GOSUB], ',');
+ if (gosub_argstart) {
+ const char *what_is_s = "s";
+ *gosub_argstart = 0;
+ if (!ast_exists_extension(peer, opt_args[OPT_ARG_CALLEE_GOSUB], "s", 1, S_COR(ast_channel_caller(peer)->id.number.valid, ast_channel_caller(peer)->id.number.str, NULL)) &&
+ ast_exists_extension(peer, opt_args[OPT_ARG_CALLEE_GOSUB], "~~s~~", 1, S_COR(ast_channel_caller(peer)->id.number.valid, ast_channel_caller(peer)->id.number.str, NULL))) {
+ what_is_s = "~~s~~";
}
-
- if (gosub_args) {
- res9 = pbx_exec(peer, theapp, gosub_args);
- if (!res9) {
- struct ast_pbx_args pbx_args;
- /* A struct initializer fails to compile for this case ... */
- memset(&pbx_args, 0, sizeof(pbx_args));
- pbx_args.no_hangup_chan = 1;
- ast_pbx_run_args(peer, &pbx_args);
- }
- ast_free(gosub_args);
- ast_debug(1, "Gosub exited with status %d\n", res9);
- } else {
- ast_log(LOG_ERROR, "Could not Allocate string for Gosub arguments -- Gosub Call Aborted!\n");
+ if (asprintf(&gosub_args, "%s,%s,1(%s)", opt_args[OPT_ARG_CALLEE_GOSUB], what_is_s, gosub_argstart + 1) < 0) {
+ ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
+ gosub_args = NULL;
+ }
+ *gosub_argstart = ',';
+ } else {
+ const char *what_is_s = "s";
+ if (!ast_exists_extension(peer, opt_args[OPT_ARG_CALLEE_GOSUB], "s", 1, S_COR(ast_channel_caller(peer)->id.number.valid, ast_channel_caller(peer)->id.number.str, NULL)) &&
+ ast_exists_extension(peer, opt_args[OPT_ARG_CALLEE_GOSUB], "~~s~~", 1, S_COR(ast_channel_caller(peer)->id.number.valid, ast_channel_caller(peer)->id.number.str, NULL))) {
+ what_is_s = "~~s~~";
+ }
+ if (asprintf(&gosub_args, "%s,%s,1", opt_args[OPT_ARG_CALLEE_GOSUB], what_is_s) < 0) {
+ ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
+ gosub_args = NULL;
}
-
- } else if (!res9) {
- ast_log(LOG_ERROR, "Could not find application Gosub\n");
- res9 = -1;
}
-
- if (ast_autoservice_stop(chan) < 0) {
- res9 = -1;
+ if (gosub_args) {
+ res9 = ast_app_exec_sub(chan, peer, gosub_args);
+ ast_free(gosub_args);
+ } else {
+ ast_log(LOG_ERROR, "Could not Allocate string for Gosub arguments -- Gosub Call Aborted!\n");
}
-
- ast_channel_lock(peer);
- if (!res9 && (gosub_result = pbx_builtin_getvar_helper(peer, "GOSUB_RESULT"))) {
+ ast_channel_lock_both(chan, peer);
+
+ if (!res9 && (gosub_result_peer = pbx_builtin_getvar_helper(peer, "GOSUB_RESULT"))) {
char *gosub_transfer_dest;
+ char *gosub_result = ast_strdupa(gosub_result_peer);
const char *gosub_retval = pbx_builtin_getvar_helper(peer, "GOSUB_RETVAL");
/* Inherit return value from the peer, so it can be used in the master */
@@ -2774,6 +2729,9 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
pbx_builtin_setvar_helper(chan, "GOSUB_RETVAL", gosub_retval);
}
+ ast_channel_unlock(peer);
+ ast_channel_unlock(chan);
+
if (!strcasecmp(gosub_result, "BUSY")) {
ast_copy_string(pa.status, gosub_result, sizeof(pa.status));
ast_set_flag64(peerflags, OPT_GO_ON);
@@ -2783,16 +2741,14 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
ast_set_flag64(peerflags, OPT_GO_ON);
res = -1;
} else if (!strcasecmp(gosub_result, "CONTINUE")) {
- /* hangup peer and keep chan alive assuming the macro has changed
- the context / exten / priority or perhaps
- the next priority in the current exten is desired.
- */
+ /* Hangup peer and continue with the next extension priority. */
ast_set_flag64(peerflags, OPT_GO_ON);
res = -1;
} else if (!strcasecmp(gosub_result, "ABORT")) {
/* Hangup both ends unless the caller has the g flag */
res = -1;
- } else if (!strncasecmp(gosub_result, "GOTO:", 5) && (gosub_transfer_dest = ast_strdupa(gosub_result + 5))) {
+ } else if (!strncasecmp(gosub_result, "GOTO:", 5)) {
+ gosub_transfer_dest = gosub_result + 5;
res = -1;
/* perform a transfer to a new extension */
if (strchr(gosub_transfer_dest, '^')) { /* context^exten^priority*/
@@ -2801,9 +2757,10 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast
ast_set_flag64(peerflags, OPT_GO_ON);
}
}
+ } else {
+ ast_channel_unlock(peer);
+ ast_channel_unlock(chan);
}
-
- ast_channel_unlock(peer);
}
if (!res) {
@@ -3091,29 +3048,16 @@ static int retrydial_exec(struct ast_channel *chan, const char *data)
static int unload_module(void)
{
int res;
- struct ast_context *con;
res = ast_unregister_application(app);
res |= ast_unregister_application(rapp);
- if ((con = ast_context_find("app_dial_gosub_virtual_context"))) {
- ast_context_remove_extension2(con, "s", 1, NULL, 0);
- ast_context_destroy(con, "app_dial"); /* leave nothing behind */
- }
-
return res;
}
static int load_module(void)
{
int res;
- struct ast_context *con;
-
- con = ast_context_find_or_create(NULL, NULL, "app_dial_gosub_virtual_context", "app_dial");
- 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, "NoOp", ast_strdup(""), ast_free_ptr, "app_dial");
res = ast_register_application_xml(app, dial_exec);
res |= ast_register_application_xml(rapp, retrydial_exec);
diff --git a/apps/app_queue.c b/apps/app_queue.c
index f7da4180f..10ef801d5 100644
--- a/apps/app_queue.c
+++ b/apps/app_queue.c
@@ -5097,28 +5097,7 @@ static int try_calling(struct queue_ent *qe, const struct ast_flags opts, char *
if (!ast_strlen_zero(macroexec)) {
ast_debug(1, "app_queue: macro=%s.\n", macroexec);
-
- res = ast_autoservice_start(qe->chan);
- if (res) {
- ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
- res = -1;
- }
-
- application = pbx_findapp("Macro");
-
- if (application) {
- res = pbx_exec(peer, application, macroexec);
- ast_debug(1, "Macro exited with status %d\n", res);
- res = 0;
- } else {
- ast_log(LOG_ERROR, "Could not find application Macro\n");
- res = -1;
- }
-
- if (ast_autoservice_stop(qe->chan) < 0) {
- ast_log(LOG_ERROR, "Could not stop autoservice on calling channel\n");
- res = -1;
- }
+ ast_app_exec_macro(qe->chan, peer, macroexec);
}
/* run a gosub for this connection if defined. The gosub simply returns, no action is taken on the result */
@@ -5131,69 +5110,40 @@ static int try_calling(struct queue_ent *qe, const struct ast_flags opts, char *
}
if (!ast_strlen_zero(gosubexec)) {
+ char *gosub_args = NULL;
+ char *gosub_argstart;
+
ast_debug(1, "app_queue: gosub=%s.\n", gosubexec);
-
- res = ast_autoservice_start(qe->chan);
- if (res) {
- ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
- res = -1;
- }
-
- application = pbx_findapp("Gosub");
-
- if (application) {
- char *gosub_args, *gosub_argstart;
-
- /* Set where we came from */
- ast_channel_context_set(peer, "app_queue_gosub_virtual_context");
- ast_channel_exten_set(peer, "s");
- ast_channel_priority_set(peer, 0);
-
- gosub_argstart = strchr(gosubexec, ',');
- if (gosub_argstart) {
- const char *what_is_s = "s";
- *gosub_argstart = 0;
- if (!ast_exists_extension(peer, gosubexec, "s", 1, S_COR(ast_channel_caller(peer)->id.number.valid, ast_channel_caller(peer)->id.number.str, NULL)) &&
- ast_exists_extension(peer, gosubexec, "~~s~~", 1, S_COR(ast_channel_caller(peer)->id.number.valid, ast_channel_caller(peer)->id.number.str, NULL))) {
- what_is_s = "~~s~~";
- }
- if (asprintf(&gosub_args, "%s,%s,1(%s)", gosubexec, what_is_s, gosub_argstart + 1) < 0) {
- ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
- gosub_args = NULL;
- }
- *gosub_argstart = ',';
- } else {
- const char *what_is_s = "s";
- if (!ast_exists_extension(peer, gosubexec, "s", 1, S_COR(ast_channel_caller(peer)->id.number.valid, ast_channel_caller(peer)->id.number.str, NULL)) &&
- ast_exists_extension(peer, gosubexec, "~~s~~", 1, S_COR(ast_channel_caller(peer)->id.number.valid, ast_channel_caller(peer)->id.number.str, NULL))) {
- what_is_s = "~~s~~";
- }
- if (asprintf(&gosub_args, "%s,%s,1", gosubexec, what_is_s) < 0) {
- ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
- gosub_args = NULL;
- }
+
+ gosub_argstart = strchr(gosubexec, ',');
+ if (gosub_argstart) {
+ const char *what_is_s = "s";
+ *gosub_argstart = 0;
+ if (!ast_exists_extension(peer, gosubexec, "s", 1, S_COR(ast_channel_caller(peer)->id.number.valid, ast_channel_caller(peer)->id.number.str, NULL)) &&
+ ast_exists_extension(peer, gosubexec, "~~s~~", 1, S_COR(ast_channel_caller(peer)->id.number.valid, ast_channel_caller(peer)->id.number.str, NULL))) {
+ what_is_s = "~~s~~";
}
- if (gosub_args) {
- res = pbx_exec(peer, application, gosub_args);
- if (!res) {
- struct ast_pbx_args args;
- memset(&args, 0, sizeof(args));
- args.no_hangup_chan = 1;
- ast_pbx_run_args(peer, &args);
- }
- ast_free(gosub_args);
- ast_debug(1, "Gosub exited with status %d\n", res);
- } else {
- ast_log(LOG_ERROR, "Could not Allocate string for Gosub arguments -- Gosub Call Aborted!\n");
+ if (asprintf(&gosub_args, "%s,%s,1(%s)", gosubexec, what_is_s, gosub_argstart + 1) < 0) {
+ ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
+ gosub_args = NULL;
}
+ *gosub_argstart = ',';
} else {
- ast_log(LOG_ERROR, "Could not find application Gosub\n");
- res = -1;
+ const char *what_is_s = "s";
+ if (!ast_exists_extension(peer, gosubexec, "s", 1, S_COR(ast_channel_caller(peer)->id.number.valid, ast_channel_caller(peer)->id.number.str, NULL)) &&
+ ast_exists_extension(peer, gosubexec, "~~s~~", 1, S_COR(ast_channel_caller(peer)->id.number.valid, ast_channel_caller(peer)->id.number.str, NULL))) {
+ what_is_s = "~~s~~";
+ }
+ if (asprintf(&gosub_args, "%s,%s,1", gosubexec, what_is_s) < 0) {
+ ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
+ gosub_args = NULL;
+ }
}
-
- if (ast_autoservice_stop(qe->chan) < 0) {
- ast_log(LOG_ERROR, "Could not stop autoservice on calling channel\n");
- res = -1;
+ if (gosub_args) {
+ ast_app_exec_sub(qe->chan, peer, gosub_args);
+ ast_free(gosub_args);
+ } else {
+ ast_log(LOG_ERROR, "Could not Allocate string for Gosub arguments -- Gosub Call Aborted!\n");
}
}
@@ -8763,7 +8713,6 @@ static const struct ast_data_entry queue_data_providers[] = {
static int unload_module(void)
{
int res;
- struct ast_context *con;
struct ao2_iterator q_iter;
struct call_queue *q = NULL;
@@ -8798,11 +8747,6 @@ static int unload_module(void)
ast_extension_state_del(0, extension_state_cb);
- if ((con = ast_context_find("app_queue_gosub_virtual_context"))) {
- ast_context_remove_extension2(con, "s", 1, NULL, 0);
- ast_context_destroy(con, "app_queue"); /* leave no trace */
- }
-
q_iter = ao2_iterator_init(queues, 0);
while ((q = ao2_t_iterator_next(&q_iter, "Iterate through queues"))) {
queues_t_unlink(queues, q, "Remove queue from container due to unload");
@@ -8818,7 +8762,6 @@ static int unload_module(void)
static int load_module(void)
{
int res;
- struct ast_context *con;
struct ast_flags mask = {AST_FLAGS_ALL, };
queues = ao2_container_alloc(MAX_QUEUE_BUCKETS, queue_hash_cb, queue_cmp_cb);
@@ -8828,12 +8771,6 @@ static int load_module(void)
if (reload_handler(0, &mask, NULL))
return AST_MODULE_LOAD_DECLINE;
- con = ast_context_find_or_create(NULL, NULL, "app_queue_gosub_virtual_context", "app_queue");
- if (!con)
- ast_log(LOG_ERROR, "Queue virtual context 'app_queue_gosub_virtual_context' does not exist and unable to create\n");
- else
- ast_add_extension2(con, 1, "s", 1, NULL, NULL, "NoOp", ast_strdup(""), ast_free_ptr, "app_queue");
-
if (queue_persistent_members)
reload_queue_members();