Mon Oct 8 12:39:08 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 = "ac1f6a56484a8820659555499174e588" , .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 }, [ '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 320 of file app_page.c.

static void __unreg_module ( void   )  [static]

Definition at line 320 of file app_page.c.

static int load_module ( void   )  [static]

Definition at line 315 of file app_page.c.

References ast_register_application_xml, and page_exec().

00316 {
00317    return ast_register_application_xml(app_page, page_exec);
00318 }

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

static int unload_module ( void   )  [static]

Definition at line 310 of file app_page.c.

References ast_unregister_application().

00311 {
00312    return ast_unregister_application(app_page);
00313 }


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

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

Referenced by page_exec().


Generated on Mon Oct 8 12:39:08 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7