Wed Apr 6 11:29:50 2011

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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .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 123 of file app_page.c.

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

enum page_opt_flags

Enumerator:
PAGE_DUPLEX 
PAGE_QUIET 
PAGE_RECORD 
PAGE_SKIP 
PAGE_IGNORE_FORWARDS 
PAGE_ANNOUNCE 
PAGE_NOCALLERANNOUNCE 

Definition at line 113 of file app_page.c.

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


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 312 of file app_page.c.

static void __unreg_module ( void   )  [static]

Definition at line 312 of file app_page.c.

static int load_module ( void   )  [static]

Definition at line 307 of file app_page.c.

References ast_register_application_xml, and page_exec().

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

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

Definition at line 140 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().

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

static int unload_module ( void   )  [static]

Definition at line 302 of file app_page.c.

References ast_unregister_application().

00303 {
00304    return ast_unregister_application(app_page);
00305 }


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

Definition at line 312 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 312 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 137 of file app_page.c.

Referenced by page_exec().


Generated on Wed Apr 6 11:29:50 2011 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7