diff options
Diffstat (limited to 'apps/app_page.c')
-rw-r--r-- | apps/app_page.c | 125 |
1 files changed, 50 insertions, 75 deletions
diff --git a/apps/app_page.c b/apps/app_page.c index bb27fde3b..b5d33e651 100644 --- a/apps/app_page.c +++ b/apps/app_page.c @@ -48,6 +48,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/app.h" #include "asterisk/chanvars.h" #include "asterisk/utils.h" +#include "asterisk/dial.h" +#include "asterisk/devicestate.h" static const char *app_page= "Page"; @@ -63,7 +65,6 @@ static const char *page_descrip = " q - quiet, do not play beep to caller\n" " r - record the page into a file (see 'r' for app_meetme)\n"; - enum { PAGE_DUPLEX = (1 << 0), PAGE_QUIET = (1 << 1), @@ -76,82 +77,18 @@ AST_APP_OPTIONS(page_opts, { AST_APP_OPTION('r', PAGE_RECORD), }); -struct calloutdata { - char cidnum[64]; - char cidname[64]; - char tech[64]; - char resource[256]; - char meetmeopts[64]; - struct ast_variable *variables; -}; - -static void *page_thread(void *data) -{ - struct calloutdata *cd = data; - ast_pbx_outgoing_app(cd->tech, AST_FORMAT_SLINEAR, cd->resource, 30000, - "MeetMe", cd->meetmeopts, NULL, 0, cd->cidnum, cd->cidname, cd->variables, NULL, NULL); - free(cd); - return NULL; -} - -static void launch_page(struct ast_channel *chan, const char *meetmeopts, const char *tech, const char *resource) -{ - struct calloutdata *cd; - const char *varname; - struct ast_variable *lastvar = NULL; - struct ast_var_t *varptr; - pthread_t t; - pthread_attr_t attr; - if ((cd = ast_calloc(1, sizeof(*cd)))) { - ast_copy_string(cd->cidnum, chan->cid.cid_num ? chan->cid.cid_num : "", sizeof(cd->cidnum)); - ast_copy_string(cd->cidname, chan->cid.cid_name ? chan->cid.cid_name : "", sizeof(cd->cidname)); - ast_copy_string(cd->tech, tech, sizeof(cd->tech)); - ast_copy_string(cd->resource, resource, sizeof(cd->resource)); - ast_copy_string(cd->meetmeopts, meetmeopts, sizeof(cd->meetmeopts)); - - AST_LIST_TRAVERSE(&chan->varshead, varptr, entries) { - if (!(varname = ast_var_full_name(varptr))) - continue; - if (varname[0] == '_') { - struct ast_variable *newvar = NULL; - - if (varname[1] == '_') { - newvar = ast_variable_new(varname, ast_var_value(varptr)); - } else { - newvar = ast_variable_new(&varname[1], ast_var_value(varptr)); - } - - if (newvar) { - if (lastvar) - lastvar->next = newvar; - else - cd->variables = newvar; - lastvar = newvar; - } - } - } - - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - if (ast_pthread_create(&t, &attr, page_thread, cd)) { - ast_log(LOG_WARNING, "Unable to create paging thread: %s\n", strerror(errno)); - free(cd); - } - } -} +#define MAX_DIALS 128 static int page_exec(struct ast_channel *chan, void *data) { struct ast_module_user *u; - char *options; - char *tech, *resource; - char meetmeopts[80]; + char *options, *tech, *resource, *tmp; + char meetmeopts[88], originator[AST_CHANNEL_NAME]; struct ast_flags flags = { 0 }; unsigned int confid = ast_random(); struct ast_app *app; - char *tmp; - int res=0; - char originator[AST_CHANNEL_NAME]; + int res = 0, pos = 0, i = 0; + struct ast_dial *dials[MAX_DIALS]; if (ast_strlen_zero(data)) { ast_log(LOG_WARNING, "This application requires at least one argument (destination(s) to page)\n"); @@ -176,20 +113,42 @@ static int page_exec(struct ast_channel *chan, void *data) if (options) ast_app_parse_options(page_opts, &flags, NULL, options); - snprintf(meetmeopts, sizeof(meetmeopts), "%ud|%s%sqxdw(5)", confid, (ast_test_flag(&flags, PAGE_DUPLEX) ? "" : "m"), + snprintf(meetmeopts, sizeof(meetmeopts), "MeetMe|%ud|%s%sqxdw(5)", confid, (ast_test_flag(&flags, PAGE_DUPLEX) ? "" : "m"), (ast_test_flag(&flags, PAGE_RECORD) ? "r" : "") ); + /* Go through parsing/calling each device */ while ((tech = strsep(&tmp, "&"))) { + struct ast_dial *dial = NULL; + /* don't call the originating device */ if (!strcasecmp(tech, originator)) continue; - if ((resource = strchr(tech, '/'))) { - *resource++ = '\0'; - launch_page(chan, meetmeopts, tech, resource); - } else { + /* If no resource is available, continue on */ + if (!(resource = strchr(tech, '/'))) { ast_log(LOG_WARNING, "Incomplete destination '%s' supplied.\n", tech); + continue; } + + *resource++ = '\0'; + + /* Create a dialing structure */ + if (!(dial = ast_dial_create())) { + ast_log(LOG_WARNING, "Failed to create dialing structure.\n"); + continue; + } + + /* Append technology and resource */ + ast_dial_append(dial, tech, resource); + + /* Set ANSWER_EXEC as global option */ + ast_dial_option_global_enable(dial, AST_DIAL_OPTION_ANSWER_EXEC, meetmeopts); + + /* Run this dial in async mode */ + ast_dial_run(dial, chan, 1); + + /* Put in our dialing array */ + dials[pos++] = dial; } if (!ast_test_flag(&flags, PAGE_QUIET)) { @@ -197,12 +156,28 @@ static int page_exec(struct ast_channel *chan, void *data) if (!res) res = ast_waitstream(chan, ""); } + if (!res) { snprintf(meetmeopts, sizeof(meetmeopts), "%ud|A%s%sqxd", confid, (ast_test_flag(&flags, PAGE_DUPLEX) ? "" : "t"), (ast_test_flag(&flags, PAGE_RECORD) ? "r" : "") ); pbx_exec(chan, app, meetmeopts); } + /* Go through each dial attempt cancelling, joining, and destroying */ + for (i = 0; i < pos; i++) { + struct ast_dial *dial = dials[i]; + + /* If the dial is already answered, then they will/should get kicked out by Meetme */ + if (ast_dial_status(dial) != AST_DIAL_RESULT_ANSWERED) + ast_dial_join(dial); + + /* Hangup all channels */ + ast_dial_hangup(dial); + + /* Destroy dialing structure */ + ast_dial_destroy(dial); + } + ast_module_user_remove(u); return -1; |