page() - Paging application More...
#include "asterisk.h"#include "asterisk/channel.h"#include "asterisk/pbx.h"#include "asterisk/module.h"#include "asterisk/file.h"#include "asterisk/app.h"#include "asterisk/chanvars.h"#include "asterisk/utils.h"#include "asterisk/devicestate.h"#include "asterisk/dial.h"
Go to the source code of this file.
Data Structures | |
| struct | page_options |
Enumerations | |
| enum | { OPT_ARG_ANNOUNCE = 0, OPT_ARG_ARRAY_SIZE = 1 } |
| enum | page_opt_flags { PAGE_DUPLEX = (1 << 0), PAGE_QUIET = (1 << 1), PAGE_RECORD = (1 << 2), PAGE_SKIP = (1 << 3), PAGE_IGNORE_FORWARDS = (1 << 4), PAGE_ANNOUNCE = (1 << 5), PAGE_NOCALLERANNOUNCE = (1 << 6) } |
Functions | |
| static void | __reg_module (void) |
| static void | __unreg_module (void) |
| static int | load_module (void) |
| static int | page_exec (struct ast_channel *chan, const char *data) |
| static void | page_state_callback (struct ast_dial *dial) |
| static void | setup_profile_bridge (struct ast_channel *chan, struct page_options *options) |
| static void | setup_profile_caller (struct ast_channel *chan, struct page_options *options) |
| static void | setup_profile_paged (struct ast_channel *chan, struct page_options *options) |
| static int | unload_module (void) |
Variables | |
| static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Page Multiple Phones" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } |
| static const char *const | app_page = "Page" |
| static struct ast_module_info * | ast_module_info = &__mod_info |
| static struct ast_app_option | page_opts [128] = { [ 'd' ] = { .flag = PAGE_DUPLEX }, [ 'q' ] = { .flag = PAGE_QUIET }, [ 'r' ] = { .flag = PAGE_RECORD }, [ 's' ] = { .flag = PAGE_SKIP }, [ 'i' ] = { .flag = PAGE_IGNORE_FORWARDS }, [ 'A' ] = { .flag = PAGE_ANNOUNCE , .arg_index = OPT_ARG_ANNOUNCE + 1 }, [ 'n' ] = { .flag = PAGE_NOCALLERANNOUNCE },} |
page() - Paging application
Definition in file app_page.c.
| anonymous enum |
Definition at line 123 of file app_page.c.
{
OPT_ARG_ANNOUNCE = 0,
OPT_ARG_ARRAY_SIZE = 1,
};
| enum page_opt_flags |
| PAGE_DUPLEX | |
| PAGE_QUIET | |
| PAGE_RECORD | |
| PAGE_SKIP | |
| PAGE_IGNORE_FORWARDS | |
| PAGE_ANNOUNCE | |
| PAGE_NOCALLERANNOUNCE |
Definition at line 113 of file app_page.c.
{
PAGE_DUPLEX = (1 << 0),
PAGE_QUIET = (1 << 1),
PAGE_RECORD = (1 << 2),
PAGE_SKIP = (1 << 3),
PAGE_IGNORE_FORWARDS = (1 << 4),
PAGE_ANNOUNCE = (1 << 5),
PAGE_NOCALLERANNOUNCE = (1 << 6),
};
| static void __reg_module | ( | void | ) | [static] |
Definition at line 391 of file app_page.c.
| static void __unreg_module | ( | void | ) | [static] |
Definition at line 391 of file app_page.c.
| static int load_module | ( | void | ) | [static] |
Definition at line 386 of file app_page.c.
References ast_register_application_xml, and page_exec().
{
return ast_register_application_xml(app_page, page_exec);
}
| static int page_exec | ( | struct ast_channel * | chan, |
| const char * | data | ||
| ) | [static] |
Definition at line 223 of file app_page.c.
References app, args, AST_APP_ARG, ast_app_parse_options(), ast_calloc, ast_channel_language(), AST_CHANNEL_NAME, ast_channel_name(), ast_copy_string(), AST_DECLARE_APP_ARGS, AST_DEVICE_NOT_INUSE, AST_DEVICE_UNKNOWN, ast_devstate2str(), ast_dial_append(), ast_dial_create(), ast_dial_destroy(), ast_dial_hangup(), ast_dial_join(), AST_DIAL_OPTION_ANSWER_EXEC, AST_DIAL_OPTION_DISABLE_CALL_FORWARDING, ast_dial_option_global_enable(), ast_dial_run(), ast_dial_set_global_timeout(), ast_dial_set_state_callback(), ast_dial_set_user_data(), ast_free, ast_log(), ast_random(), AST_STANDARD_APP_ARGS, ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_waitstream(), page_options::flags, LOG_ERROR, LOG_WARNING, page_options::opts, PAGE_IGNORE_FORWARDS, page_opts, PAGE_QUIET, PAGE_SKIP, page_state_callback(), parse(), pbx_exec(), pbx_findapp(), setup_profile_bridge(), setup_profile_caller(), and ast_dial::timeout.
Referenced by load_module().
{
char *tech, *resource, *tmp;
char confbridgeopts[128], 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;
struct ast_dial **dial_list;
unsigned int num_dials;
int timeout = 0;
char *parse;
AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(devices);
AST_APP_ARG(options);
AST_APP_ARG(timeout);
);
if (ast_strlen_zero(data)) {
ast_log(LOG_WARNING, "This application requires at least one argument (destination(s) to page)\n");
return -1;
}
if (!(app = pbx_findapp("ConfBridge"))) {
ast_log(LOG_WARNING, "There is no ConfBridge application available!\n");
return -1;
};
parse = ast_strdupa(data);
AST_STANDARD_APP_ARGS(args, parse);
ast_copy_string(originator, ast_channel_name(chan), sizeof(originator));
if ((tmp = strchr(originator, '-'))) {
*tmp = '\0';
}
if (!ast_strlen_zero(args.options)) {
ast_app_parse_options(page_opts, &options.flags, options.opts, args.options);
}
if (!ast_strlen_zero(args.timeout)) {
timeout = atoi(args.timeout);
}
snprintf(confbridgeopts, sizeof(confbridgeopts), "ConfBridge,%u", confid);
/* Count number of extensions in list by number of ampersands + 1 */
num_dials = 1;
tmp = args.devices;
while (*tmp) {
if (*tmp == '&') {
num_dials++;
}
tmp++;
}
if (!(dial_list = ast_calloc(num_dials, sizeof(struct ast_dial *)))) {
ast_log(LOG_ERROR, "Can't allocate %ld bytes for dial list\n", (long)(sizeof(struct ast_dial *) * num_dials));
return -1;
}
/* Go through parsing/calling each device */
while ((tech = strsep(&args.devices, "&"))) {
int state = 0;
struct ast_dial *dial = NULL;
/* don't call the originating device */
if (!strcasecmp(tech, originator))
continue;
/* If no resource is available, continue on */
if (!(resource = strchr(tech, '/'))) {
ast_log(LOG_WARNING, "Incomplete destination '%s' supplied.\n", tech);
continue;
}
/* Ensure device is not in use if skip option is enabled */
if (ast_test_flag(&options.flags, PAGE_SKIP)) {
state = ast_device_state(tech);
if (state == AST_DEVICE_UNKNOWN) {
ast_log(LOG_WARNING, "Destination '%s' has device state '%s'. Paging anyway.\n", tech, ast_devstate2str(state));
} else if (state != AST_DEVICE_NOT_INUSE) {
ast_log(LOG_WARNING, "Destination '%s' has device state '%s'.\n", tech, ast_devstate2str(state));
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 */
if (ast_dial_append(dial, tech, resource) == -1) {
ast_log(LOG_ERROR, "Failed to add %s to outbound dial\n", tech);
ast_dial_destroy(dial);
continue;
}
/* Set ANSWER_EXEC as global option */
ast_dial_option_global_enable(dial, AST_DIAL_OPTION_ANSWER_EXEC, confbridgeopts);
if (timeout) {
ast_dial_set_global_timeout(dial, timeout * 1000);
}
if (ast_test_flag(&options.flags, PAGE_IGNORE_FORWARDS)) {
ast_dial_option_global_enable(dial, AST_DIAL_OPTION_DISABLE_CALL_FORWARDING, NULL);
}
ast_dial_set_state_callback(dial, &page_state_callback);
ast_dial_set_user_data(dial, &options);
/* Run this dial in async mode */
ast_dial_run(dial, chan, 1);
/* Put in our dialing array */
dial_list[pos++] = dial;
}
if (!ast_test_flag(&options.flags, PAGE_QUIET)) {
res = ast_streamfile(chan, "beep", ast_channel_language(chan));
if (!res)
res = ast_waitstream(chan, "");
}
if (!res) {
setup_profile_bridge(chan, &options);
setup_profile_caller(chan, &options);
snprintf(confbridgeopts, sizeof(confbridgeopts), "%u", confid);
pbx_exec(chan, app, confbridgeopts);
}
/* Go through each dial attempt cancelling, joining, and destroying */
for (i = 0; i < pos; i++) {
struct ast_dial *dial = dial_list[i];
/* We have to wait for the async thread to exit as it's possible ConfBridge won't throw them out immediately */
ast_dial_join(dial);
/* Hangup all channels */
ast_dial_hangup(dial);
/* Destroy dialing structure */
ast_dial_destroy(dial);
}
ast_free(dial_list);
return -1;
}
| static void page_state_callback | ( | struct ast_dial * | dial | ) | [static] |
Definition at line 208 of file app_page.c.
References ast_dial_answered(), ast_dial_get_user_data(), AST_DIAL_RESULT_ANSWERED, ast_dial_state(), setup_profile_bridge(), and setup_profile_paged().
Referenced by page_exec().
{
struct ast_channel *chan;
struct page_options *options;
if (ast_dial_state(dial) != AST_DIAL_RESULT_ANSWERED ||
!(chan = ast_dial_answered(dial)) ||
!(options = ast_dial_get_user_data(dial))) {
return;
}
setup_profile_bridge(chan, options);
setup_profile_paged(chan, options);
}
| static void setup_profile_bridge | ( | struct ast_channel * | chan, |
| struct page_options * | options | ||
| ) | [static] |
Definition at line 153 of file app_page.c.
References ast_func_write(), ast_test_flag, page_options::flags, and PAGE_RECORD.
Referenced by page_exec(), and page_state_callback().
{
/* Use default_bridge as a starting point */
ast_func_write(chan, "CONFBRIDGE(bridge,template)", "");
if (ast_test_flag(&options->flags, PAGE_RECORD)) {
ast_func_write(chan, "CONFBRIDGE(bridge,record_conference)", "yes");
}
}
| static void setup_profile_caller | ( | struct ast_channel * | chan, |
| struct page_options * | options | ||
| ) | [static] |
Definition at line 195 of file app_page.c.
References ast_func_write(), ast_strlen_zero(), ast_test_flag, page_options::flags, OPT_ARG_ANNOUNCE, page_options::opts, PAGE_ANNOUNCE, and PAGE_NOCALLERANNOUNCE.
Referenced by page_exec().
{
/* Use default_user as a starting point if not already setup. */
ast_func_write(chan, "CONFBRIDGE(user,template)", "");
ast_func_write(chan, "CONFBRIDGE(user,quiet)", "yes");
ast_func_write(chan, "CONFBRIDGE(user,marked)", "yes");
if (!ast_test_flag(&options->flags, PAGE_NOCALLERANNOUNCE)
&& ast_test_flag(&options->flags, PAGE_ANNOUNCE)
&& !ast_strlen_zero(options->opts[OPT_ARG_ANNOUNCE])) {
ast_func_write(chan, "CONFBRIDGE(user,announcement)", options->opts[OPT_ARG_ANNOUNCE]);
}
}
| static void setup_profile_paged | ( | struct ast_channel * | chan, |
| struct page_options * | options | ||
| ) | [static] |
Definition at line 171 of file app_page.c.
References ast_func_write(), ast_strlen_zero(), ast_test_flag, page_options::flags, OPT_ARG_ANNOUNCE, page_options::opts, PAGE_ANNOUNCE, and PAGE_DUPLEX.
Referenced by page_state_callback().
{
/* Use default_user as a starting point */
ast_func_write(chan, "CONFBRIDGE(user,template)", "");
ast_func_write(chan, "CONFBRIDGE(user,quiet)", "yes");
ast_func_write(chan, "CONFBRIDGE(user,end_marked)", "yes");
if (!ast_test_flag(&options->flags, PAGE_DUPLEX)) {
ast_func_write(chan, "CONFBRIDGE(user,startmuted)", "yes");
}
if (ast_test_flag(&options->flags, PAGE_ANNOUNCE)
&& !ast_strlen_zero(options->opts[OPT_ARG_ANNOUNCE])) {
ast_func_write(chan, "CONFBRIDGE(user,announcement)", options->opts[OPT_ARG_ANNOUNCE]);
}
}
| static int unload_module | ( | void | ) | [static] |
Definition at line 381 of file app_page.c.
References ast_unregister_application().
{
return ast_unregister_application(app_page);
}
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Page Multiple Phones" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } [static] |
Definition at line 391 of file app_page.c.
const char* const app_page = "Page" [static] |
Definition at line 111 of file app_page.c.
struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 391 of file app_page.c.
struct ast_app_option page_opts[128] = { [ 'd' ] = { .flag = PAGE_DUPLEX }, [ 'q' ] = { .flag = PAGE_QUIET }, [ 'r' ] = { .flag = PAGE_RECORD }, [ 's' ] = { .flag = PAGE_SKIP }, [ 'i' ] = { .flag = PAGE_IGNORE_FORWARDS }, [ 'A' ] = { .flag = PAGE_ANNOUNCE , .arg_index = OPT_ARG_ANNOUNCE + 1 }, [ 'n' ] = { .flag = PAGE_NOCALLERANNOUNCE },} [static] |
Definition at line 136 of file app_page.c.
Referenced by page_exec().