Mon Mar 20 08:20:06 2006

Asterisk developer's documentation


Main Page | Modules | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

app_page.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (c) 2004 - 2005 Digium, Inc.  All rights reserved.
00005  *
00006  * Mark Spencer <markster@digium.com>
00007  *
00008  * This code is released under the GNU General Public License
00009  * version 2.0.  See LICENSE for more information.
00010  *
00011  * See http://www.asterisk.org for more information about
00012  * the Asterisk project. Please do not directly contact
00013  * any of the maintainers of this project for assistance;
00014  * the project provides a web site, mailing lists and IRC
00015  * channels for your use.
00016  *
00017  */
00018 
00019 /*! \file
00020  *
00021  * \brief page() - Paging application
00022  *
00023  * \ingroup applications
00024  */
00025 
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include <unistd.h>
00029 #include <string.h>
00030 #include <errno.h>
00031 
00032 #include "asterisk.h"
00033 
00034 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 9607 $")
00035 
00036 #include "asterisk/options.h"
00037 #include "asterisk/logger.h"
00038 #include "asterisk/channel.h"
00039 #include "asterisk/pbx.h"
00040 #include "asterisk/module.h"
00041 #include "asterisk/file.h"
00042 #include "asterisk/app.h"
00043 #include "asterisk/chanvars.h"
00044 
00045 
00046 static const char *tdesc = "Page Multiple Phones";
00047 
00048 static const char *app_page= "Page";
00049 
00050 static const char *page_synopsis = "Pages phones";
00051 
00052 static const char *page_descrip =
00053 "Page(Technology/Resource&Technology2/Resource2[|options])\n"
00054 "  Places outbound calls to the given technology / resource and dumps\n"
00055 "them into a conference bridge as muted participants.  The original\n"
00056 "caller is dumped into the conference as a speaker and the room is\n"
00057 "destroyed when the original caller leaves.  Valid options are:\n"
00058 "        d - full duplex audio\n"
00059 "   q - quiet, do not play beep to caller\n";
00060 
00061 STANDARD_LOCAL_USER;
00062 
00063 LOCAL_USER_DECL;
00064 
00065 enum {
00066    PAGE_DUPLEX = (1 << 0),
00067    PAGE_QUIET = (1 << 1),
00068 } page_opt_flags;
00069 
00070 AST_APP_OPTIONS(page_opts, {
00071    AST_APP_OPTION('d', PAGE_DUPLEX),
00072    AST_APP_OPTION('q', PAGE_QUIET),
00073 });
00074 
00075 struct calloutdata {
00076    char cidnum[64];
00077    char cidname[64];
00078    char tech[64];
00079    char resource[256];
00080    char meetmeopts[64];
00081    struct ast_variable *variables;
00082 };
00083 
00084 static void *page_thread(void *data)
00085 {
00086    struct calloutdata *cd = data;
00087    ast_pbx_outgoing_app(cd->tech, AST_FORMAT_SLINEAR, cd->resource, 30000,
00088       "MeetMe", cd->meetmeopts, NULL, 0, cd->cidnum, cd->cidname, cd->variables, NULL, NULL);
00089    free(cd);
00090    return NULL;
00091 }
00092 
00093 static void launch_page(struct ast_channel *chan, const char *meetmeopts, const char *tech, const char *resource)
00094 {
00095    struct calloutdata *cd;
00096    const char *varname;
00097    struct ast_variable *lastvar = NULL;
00098    struct ast_var_t *varptr;
00099    pthread_t t;
00100    pthread_attr_t attr;
00101    cd = malloc(sizeof(struct calloutdata));
00102    if (cd) {
00103       memset(cd, 0, sizeof(struct calloutdata));
00104       ast_copy_string(cd->cidnum, chan->cid.cid_num ? chan->cid.cid_num : "", sizeof(cd->cidnum));
00105       ast_copy_string(cd->cidname, chan->cid.cid_name ? chan->cid.cid_name : "", sizeof(cd->cidname));
00106       ast_copy_string(cd->tech, tech, sizeof(cd->tech));
00107       ast_copy_string(cd->resource, resource, sizeof(cd->resource));
00108       ast_copy_string(cd->meetmeopts, meetmeopts, sizeof(cd->meetmeopts));
00109 
00110       AST_LIST_TRAVERSE(&chan->varshead, varptr, entries) {
00111          if (!(varname = ast_var_full_name(varptr)))
00112             continue;
00113          if (varname[0] == '_') {
00114             struct ast_variable *newvar = NULL;
00115 
00116             if (varname[1] == '_') {
00117                newvar = ast_variable_new(varname, ast_var_value(varptr));
00118             } else {
00119                newvar = ast_variable_new(&varname[1], ast_var_value(varptr));
00120             }
00121 
00122             if (newvar) {
00123                if (lastvar)
00124                   lastvar->next = newvar;
00125                else
00126                   cd->variables = newvar;
00127                lastvar = newvar;
00128             }
00129          }
00130       }
00131 
00132       pthread_attr_init(&attr);
00133       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
00134       if (ast_pthread_create(&t, &attr, page_thread, cd)) {
00135          ast_log(LOG_WARNING, "Unable to create paging thread: %s\n", strerror(errno));
00136          free(cd);
00137       }
00138    }
00139 }
00140 
00141 static int page_exec(struct ast_channel *chan, void *data)
00142 {
00143    struct localuser *u;
00144    char *options;
00145    char *tech, *resource;
00146    char meetmeopts[80];
00147    struct ast_flags flags = { 0 };
00148    unsigned int confid = rand();
00149    struct ast_app *app;
00150    char *tmp;
00151    int res=0;
00152 
00153    if (ast_strlen_zero(data)) {
00154       ast_log(LOG_WARNING, "This application requires at least one argument (destination(s) to page)\n");
00155       return -1;
00156    }
00157 
00158    LOCAL_USER_ADD(u);
00159 
00160    if (!(app = pbx_findapp("MeetMe"))) {
00161       ast_log(LOG_WARNING, "There is no MeetMe application available!\n");
00162       LOCAL_USER_REMOVE(u);
00163       return -1;
00164    };
00165 
00166    options = ast_strdupa(data);
00167    if (!options) {
00168       ast_log(LOG_ERROR, "Out of memory\n");
00169       LOCAL_USER_REMOVE(u);
00170       return -1;
00171    }
00172 
00173    tmp = strsep(&options, "|");
00174    if (options)
00175       ast_app_parse_options(page_opts, &flags, NULL, options);
00176 
00177    snprintf(meetmeopts, sizeof(meetmeopts), "%ud|%sqxdw", confid, ast_test_flag(&flags, PAGE_DUPLEX) ? "" : "m");
00178    while ((tech = strsep(&tmp, "&"))) {
00179       if ((resource = strchr(tech, '/'))) {
00180          *resource++ = '\0';
00181          launch_page(chan, meetmeopts, tech, resource);
00182       } else {
00183          ast_log(LOG_WARNING, "Incomplete destination '%s' supplied.\n", tech);
00184       }
00185    }
00186    if (!ast_test_flag(&flags, PAGE_QUIET)) {
00187       res = ast_streamfile(chan, "beep", chan->language);
00188       if (!res)
00189          res = ast_waitstream(chan, "");
00190    }
00191    if (!res) {
00192       snprintf(meetmeopts, sizeof(meetmeopts), "%ud|A%sqxd", confid, ast_test_flag(&flags, PAGE_DUPLEX) ? "" : "t");
00193       pbx_exec(chan, app, meetmeopts, 1);
00194    }
00195 
00196    LOCAL_USER_REMOVE(u);
00197 
00198    return -1;
00199 }
00200 
00201 int unload_module(void)
00202 {
00203    int res;
00204 
00205    res =  ast_unregister_application(app_page);
00206 
00207    STANDARD_HANGUP_LOCALUSERS;
00208 
00209    return res;
00210 }
00211 
00212 int load_module(void)
00213 {
00214    return ast_register_application(app_page, page_exec, page_synopsis, page_descrip);
00215 }
00216 
00217 char *description(void)
00218 {
00219    return (char *) tdesc;
00220 }
00221 
00222 int usecount(void)
00223 {
00224    int res;
00225 
00226    STANDARD_USECOUNT(res);
00227 
00228    return res;
00229 }
00230 
00231 char *key()
00232 {
00233    return ASTERISK_GPL_KEY;
00234 }

Generated on Mon Mar 20 08:20:06 2006 for Asterisk - the Open Source PBX by  doxygen 1.3.9.1