Sat Mar 10 01:54:34 2012

Asterisk developer's documentation


app_page.c File Reference

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.

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 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 = "88eaa8f5c1bd988bedd71113385e0886" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, }
static const char *const app_page = "Page"
static struct ast_module_infoast_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 }, [ 'i' ] = { .flag = PAGE_IGNORE_FORWARDS }, [ 'A' ] = { .flag = PAGE_ANNOUNCE , .arg_index = OPT_ARG_ANNOUNCE + 1 }, [ 'n' ] = { .flag = PAGE_NOCALLERANNOUNCE },}


Detailed Description

page() - Paging application

Author:
Mark Spencer <markster@digium.com>

Definition in file app_page.c.


Enumeration Type Documentation

anonymous enum

Enumerator:
OPT_ARG_ANNOUNCE 
OPT_ARG_ARRAY_SIZE 

Definition at line 124 of file app_page.c.

00124      {
00125    OPT_ARG_ANNOUNCE = 0,
00126    OPT_ARG_ARRAY_SIZE = 1,
00127 };

enum page_opt_flags

Enumerator:
PAGE_DUPLEX 
PAGE_QUIET 
PAGE_RECORD 
PAGE_SKIP 
PAGE_IGNORE_FORWARDS 
PAGE_ANNOUNCE 
PAGE_NOCALLERANNOUNCE 

Definition at line 114 of file app_page.c.

00114                     {
00115    PAGE_DUPLEX = (1 << 0),
00116    PAGE_QUIET = (1 << 1),
00117    PAGE_RECORD = (1 << 2),
00118    PAGE_SKIP = (1 << 3),
00119    PAGE_IGNORE_FORWARDS = (1 << 4),
00120    PAGE_ANNOUNCE = (1 << 5),
00121    PAGE_NOCALLERANNOUNCE = (1 << 6),
00122 };


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 313 of file app_page.c.

static void __unreg_module ( void   )  [static]

Definition at line 313 of file app_page.c.

static int load_module ( void   )  [static]

Definition at line 308 of file app_page.c.

References ast_register_application_xml, and page_exec().

00309 {
00310    return ast_register_application_xml(app_page, page_exec);
00311 }

static int page_exec ( struct ast_channel chan,
const char *  data 
) [static]

Definition at line 141 of file app_page.c.

References app, args, AST_APP_ARG, ast_app_parse_options(), ast_calloc, AST_CHANNEL_NAME, ast_copy_string(), AST_DECLARE_APP_ARGS, AST_DEVICE_NOT_INUSE, ast_device_state(), 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_log(), ast_random(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_streamfile(), ast_strlen_zero(), ast_test_flag, ast_waitstream(), ast_flags::flags, ast_channel::language, LOG_ERROR, LOG_WARNING, ast_channel::name, OPT_ARG_ANNOUNCE, OPT_ARG_ARRAY_SIZE, ast_dial::options, PAGE_ANNOUNCE, PAGE_DUPLEX, PAGE_IGNORE_FORWARDS, PAGE_NOCALLERANNOUNCE, page_opts, PAGE_QUIET, PAGE_RECORD, PAGE_SKIP, parse(), pbx_exec(), pbx_findapp(), strsep(), and ast_dial::timeout.

Referenced by load_module().

00142 {
00143    char *tech, *resource, *tmp;
00144    char meetmeopts[128], originator[AST_CHANNEL_NAME], *opts[OPT_ARG_ARRAY_SIZE];
00145    struct ast_flags flags = { 0 };
00146    unsigned int confid = ast_random();
00147    struct ast_app *app;
00148    int res = 0, pos = 0, i = 0;
00149    struct ast_dial **dial_list;
00150    unsigned int num_dials;
00151    int timeout = 0;
00152    char *parse;
00153 
00154    AST_DECLARE_APP_ARGS(args,
00155       AST_APP_ARG(devices);
00156       AST_APP_ARG(options);
00157       AST_APP_ARG(timeout);
00158    );
00159 
00160    if (ast_strlen_zero(data)) {
00161       ast_log(LOG_WARNING, "This application requires at least one argument (destination(s) to page)\n");
00162       return -1;
00163    }
00164 
00165    if (!(app = pbx_findapp("MeetMe"))) {
00166       ast_log(LOG_WARNING, "There is no MeetMe application available!\n");
00167       return -1;
00168    };
00169 
00170    parse = ast_strdupa(data);
00171 
00172    AST_STANDARD_APP_ARGS(args, parse);
00173 
00174    ast_copy_string(originator, chan->name, sizeof(originator));
00175    if ((tmp = strchr(originator, '-'))) {
00176       *tmp = '\0';
00177    }
00178 
00179    if (!ast_strlen_zero(args.options)) {
00180       ast_app_parse_options(page_opts, &flags, opts, args.options);
00181    }
00182 
00183    if (!ast_strlen_zero(args.timeout)) {
00184       timeout = atoi(args.timeout);
00185    }
00186 
00187    if (ast_test_flag(&flags, PAGE_ANNOUNCE) && !ast_strlen_zero(opts[OPT_ARG_ANNOUNCE])) {
00188       snprintf(meetmeopts, sizeof(meetmeopts), "MeetMe,%ud,%s%sqxdw(5)G(%s)", confid, (ast_test_flag(&flags, PAGE_DUPLEX) ? "" : "m"),
00189                    (ast_test_flag(&flags, PAGE_RECORD) ? "r" : ""), opts[OPT_ARG_ANNOUNCE] );
00190    } else {
00191       snprintf(meetmeopts, sizeof(meetmeopts), "MeetMe,%ud,%s%sqxdw(5)", confid, (ast_test_flag(&flags, PAGE_DUPLEX) ? "" : "m"),
00192       (ast_test_flag(&flags, PAGE_RECORD) ? "r" : "") );
00193    }
00194 
00195    /* Count number of extensions in list by number of ampersands + 1 */
00196    num_dials = 1;
00197    tmp = args.devices;
00198    while (*tmp) {
00199       if (*tmp == '&') {
00200          num_dials++;
00201       }
00202       tmp++;
00203    }
00204 
00205    if (!(dial_list = ast_calloc(num_dials, sizeof(struct ast_dial *)))) {
00206       ast_log(LOG_ERROR, "Can't allocate %ld bytes for dial list\n", (long)(sizeof(struct ast_dial *) * num_dials));
00207       return -1;
00208    }
00209 
00210    /* Go through parsing/calling each device */
00211    while ((tech = strsep(&args.devices, "&"))) {
00212       int state = 0;
00213       struct ast_dial *dial = NULL;
00214 
00215       /* don't call the originating device */
00216       if (!strcasecmp(tech, originator))
00217          continue;
00218 
00219       /* If no resource is available, continue on */
00220       if (!(resource = strchr(tech, '/'))) {
00221          ast_log(LOG_WARNING, "Incomplete destination '%s' supplied.\n", tech);
00222          continue;
00223       }
00224 
00225       /* Ensure device is not in use if skip option is enabled */
00226       if (ast_test_flag(&flags, PAGE_SKIP)) {
00227          state = ast_device_state(tech);
00228          if (state == AST_DEVICE_UNKNOWN) {
00229             ast_log(LOG_WARNING, "Destination '%s' has device state '%s'. Paging anyway.\n", tech, ast_devstate2str(state));
00230          } else if (state != AST_DEVICE_NOT_INUSE) {
00231             ast_log(LOG_WARNING, "Destination '%s' has device state '%s'.\n", tech, ast_devstate2str(state));
00232             continue;
00233          }
00234       }
00235 
00236       *resource++ = '\0';
00237 
00238       /* Create a dialing structure */
00239       if (!(dial = ast_dial_create())) {
00240          ast_log(LOG_WARNING, "Failed to create dialing structure.\n");
00241          continue;
00242       }
00243 
00244       /* Append technology and resource */
00245       if (ast_dial_append(dial, tech, resource) == -1) {
00246          ast_log(LOG_ERROR, "Failed to add %s to outbound dial\n", tech);
00247          continue;
00248       }
00249 
00250       /* Set ANSWER_EXEC as global option */
00251       ast_dial_option_global_enable(dial, AST_DIAL_OPTION_ANSWER_EXEC, meetmeopts);
00252 
00253       if (timeout) {
00254          ast_dial_set_global_timeout(dial, timeout * 1000);
00255       }
00256 
00257       if (ast_test_flag(&flags, PAGE_IGNORE_FORWARDS)) {
00258          ast_dial_option_global_enable(dial, AST_DIAL_OPTION_DISABLE_CALL_FORWARDING, NULL);
00259       }
00260 
00261       /* Run this dial in async mode */
00262       ast_dial_run(dial, chan, 1);
00263 
00264       /* Put in our dialing array */
00265       dial_list[pos++] = dial;
00266    }
00267 
00268    if (!ast_test_flag(&flags, PAGE_QUIET)) {
00269       res = ast_streamfile(chan, "beep", chan->language);
00270       if (!res)
00271          res = ast_waitstream(chan, "");
00272    }
00273 
00274    if (!res) {
00275       /* Default behaviour */
00276       snprintf(meetmeopts, sizeof(meetmeopts), "%ud,A%s%sqxd", confid, (ast_test_flag(&flags, PAGE_DUPLEX) ? "" : "t"), 
00277          (ast_test_flag(&flags, PAGE_RECORD) ? "r" : "") );
00278       if (ast_test_flag(&flags, PAGE_ANNOUNCE) && !ast_strlen_zero(opts[OPT_ARG_ANNOUNCE]) &&
00279             !ast_test_flag(&flags, PAGE_NOCALLERANNOUNCE)) {
00280          snprintf(meetmeopts, sizeof(meetmeopts), "%ud,A%s%sqxdG(%s)", confid, (ast_test_flag(&flags, PAGE_DUPLEX) ? "" : "t"), 
00281            (ast_test_flag(&flags, PAGE_RECORD) ? "r" : ""), opts[OPT_ARG_ANNOUNCE] );
00282       }
00283       pbx_exec(chan, app, meetmeopts);
00284    }
00285 
00286    /* Go through each dial attempt cancelling, joining, and destroying */
00287    for (i = 0; i < pos; i++) {
00288       struct ast_dial *dial = dial_list[i];
00289 
00290       /* We have to wait for the async thread to exit as it's possible Meetme won't throw them out immediately */
00291       ast_dial_join(dial);
00292 
00293       /* Hangup all channels */
00294       ast_dial_hangup(dial);
00295 
00296       /* Destroy dialing structure */
00297       ast_dial_destroy(dial);
00298    }
00299 
00300    return -1;
00301 }

static int unload_module ( void   )  [static]

Definition at line 303 of file app_page.c.

References ast_unregister_application().

00304 {
00305    return ast_unregister_application(app_page);
00306 }


Variable Documentation

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 = "88eaa8f5c1bd988bedd71113385e0886" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } [static]

Definition at line 313 of file app_page.c.

const char* const app_page = "Page" [static]

Definition at line 112 of file app_page.c.

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 313 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 }, [ 'i' ] = { .flag = PAGE_IGNORE_FORWARDS }, [ 'A' ] = { .flag = PAGE_ANNOUNCE , .arg_index = OPT_ARG_ANNOUNCE + 1 }, [ 'n' ] = { .flag = PAGE_NOCALLERANNOUNCE },} [static]

Definition at line 138 of file app_page.c.

Referenced by page_exec().


Generated on Sat Mar 10 01:54:34 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7