Fri Nov 12 11:50:44 2010

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"
Include dependency graph for app_page.c:

Go to the source code of this file.

Enumerations

enum  {
  PAGE_DUPLEX = (1 << 0), PAGE_QUIET = (1 << 1), PAGE_RECORD = (1 << 2), PAGE_SKIP = (1 << 3),
  PAGE_IGNORE_FORWARDS = (1 << 4)
}

Functions

static void __reg_module (void)
static void __unreg_module (void)
static int load_module (void)
static int page_exec (struct ast_channel *chan, void *data)
static int unload_module (void)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .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 = "0901e4e500243c855563a2d78b0c03e4" , .load = load_module, .unload = unload_module, }
static const char * app_page = "Page"
static struct ast_module_infoast_module_info = &__mod_info
enum { ... }  page_opt_flags
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 },}

Detailed Description

page() - Paging application

Author:
Mark Spencer <markster@digium.com>

Definition in file app_page.c.


Enumeration Type Documentation

anonymous enum
Enumerator:
PAGE_DUPLEX 
PAGE_QUIET 
PAGE_RECORD 
PAGE_SKIP 
PAGE_IGNORE_FORWARDS 

Definition at line 104 of file app_page.c.

00104      {
00105    PAGE_DUPLEX = (1 << 0),
00106    PAGE_QUIET = (1 << 1),
00107    PAGE_RECORD = (1 << 2),
00108    PAGE_SKIP = (1 << 3),
00109    PAGE_IGNORE_FORWARDS = (1 << 4),
00110 } page_opt_flags;


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 282 of file app_page.c.

static void __unreg_module ( void   )  [static]

Definition at line 282 of file app_page.c.

static int load_module ( void   )  [static]

Definition at line 277 of file app_page.c.

References ast_register_application_xml, and page_exec().

00278 {
00279    return ast_register_application_xml(app_page, page_exec);
00280 }

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

Definition at line 121 of file app_page.c.

References app, 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_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_streamfile(), ast_strlen_zero(), ast_test_flag, ast_waitstream(), ast_channel::language, LOG_ERROR, LOG_WARNING, ast_channel::name, ast_dial::options, PAGE_DUPLEX, PAGE_IGNORE_FORWARDS, page_opts, PAGE_QUIET, PAGE_RECORD, PAGE_SKIP, parse(), pbx_exec(), pbx_findapp(), and ast_dial::timeout.

Referenced by load_module().

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

static int unload_module ( void   )  [static]

Definition at line 272 of file app_page.c.

References ast_unregister_application().

00273 {
00274    return ast_unregister_application(app_page);
00275 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .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 = "0901e4e500243c855563a2d78b0c03e4" , .load = load_module, .unload = unload_module, } [static]

Definition at line 282 of file app_page.c.

const char* app_page = "Page" [static]

Definition at line 102 of file app_page.c.

Definition at line 282 of file app_page.c.

enum { ... } page_opt_flags
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 },} [static]

Definition at line 118 of file app_page.c.

Referenced by page_exec().


Generated by  doxygen 1.6.2