Wed Aug 18 22:33:41 2010

Asterisk developer's documentation


app_parkandannounce.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2006, Digium, Inc.
00005  *
00006  * Mark Spencer <markster@digium.com>
00007  *
00008  * Author: Ben Miller <bgmiller@dccinc.com>
00009  *    With TONS of help from Mark!
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  * This program is free software, distributed under the terms of
00018  * the GNU General Public License Version 2. See the LICENSE file
00019  * at the top of the source tree.
00020  */
00021 
00022 /*! \file
00023  *
00024  * \brief ParkAndAnnounce application for Asterisk
00025  *
00026  * \author Ben Miller <bgmiller@dccinc.com>
00027  * \arg With TONS of help from Mark!
00028  *
00029  * \ingroup applications
00030  */
00031 
00032 #include "asterisk.h"
00033 
00034 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 170049 $")
00035 
00036 #include "asterisk/file.h"
00037 #include "asterisk/channel.h"
00038 #include "asterisk/pbx.h"
00039 #include "asterisk/module.h"
00040 #include "asterisk/features.h"
00041 #include "asterisk/say.h"
00042 #include "asterisk/lock.h"
00043 #include "asterisk/utils.h"
00044 #include "asterisk/app.h"
00045 
00046 static char *app = "ParkAndAnnounce";
00047 
00048 static char *synopsis = "Park and Announce";
00049 
00050 static char *descrip =
00051 "  ParkAndAnnounce(announce:template,timeout,dial[,return_context]):\n"
00052 "Park a call into the parkinglot and announce the call to another channel.\n"
00053 "\n"
00054 "announce template: Colon-separated list of files to announce.  The word PARKED\n"
00055 "                   will be replaced by a say_digits of the extension in which\n"
00056 "                   the call is parked.\n"
00057 "timeout:           Time in seconds before the call returns into the return\n"
00058 "                   context.\n"
00059 "dial:              The app_dial style resource to call to make the\n"
00060 "                   announcement.  Console/dsp calls the console.\n"
00061 "return_context:    The goto-style label to jump the call back into after\n"
00062 "                   timeout.  Default <priority+1>.\n"
00063 "\n"
00064 "The variable ${PARKEDAT} will contain the parking extension into which the\n"
00065 "call was placed.  Use with the Local channel to allow the dialplan to make\n"
00066 "use of this information.\n";
00067 
00068 
00069 static int parkandannounce_exec(struct ast_channel *chan, void *data)
00070 {
00071    int res = -1;
00072    int lot, timeout = 0, dres;
00073    char *dialtech, *tmp[100], buf[13];
00074    int looptemp, i;
00075    char *s;
00076 
00077    struct ast_channel *dchan;
00078    struct outgoing_helper oh = { 0, };
00079    int outstate;
00080    AST_DECLARE_APP_ARGS(args,
00081       AST_APP_ARG(template);
00082       AST_APP_ARG(timeout);
00083       AST_APP_ARG(dial);
00084       AST_APP_ARG(return_context);
00085    );
00086    if (ast_strlen_zero(data)) {
00087       ast_log(LOG_WARNING, "ParkAndAnnounce requires arguments: (announce:template|timeout|dial|[return_context])\n");
00088       return -1;
00089    }
00090   
00091    s = ast_strdupa(data);
00092    AST_STANDARD_APP_ARGS(args, s);
00093 
00094    if (args.timeout)
00095       timeout = atoi(args.timeout) * 1000;
00096 
00097    if (ast_strlen_zero(args.dial)) {
00098       ast_log(LOG_WARNING, "PARK: A dial resource must be specified i.e: Console/dsp or DAHDI/g1/5551212\n");
00099       return -1;
00100    }
00101 
00102    dialtech = strsep(&args.dial, "/");
00103    ast_verb(3, "Dial Tech,String: (%s,%s)\n", dialtech, args.dial);
00104 
00105    if (!ast_strlen_zero(args.return_context)) {
00106       ast_clear_flag(chan, AST_FLAG_IN_AUTOLOOP);
00107       ast_parseable_goto(chan, args.return_context);
00108    }
00109 
00110    ast_verb(3, "Return Context: (%s,%s,%d) ID: %s\n", chan->context, chan->exten, chan->priority, chan->cid.cid_num);
00111       if (!ast_exists_extension(chan, chan->context, chan->exten, chan->priority, chan->cid.cid_num)) {
00112       ast_verb(3, "Warning: Return Context Invalid, call will return to default|s\n");
00113       }
00114 
00115    /* we are using masq_park here to protect * from touching the channel once we park it.  If the channel comes out of timeout
00116    before we are done announcing and the channel is messed with, Kablooeee.  So we use Masq to prevent this.  */
00117 
00118    res = ast_masq_park_call(chan, NULL, timeout, &lot);
00119    if (res == -1)
00120       return res;
00121 
00122    ast_verb(3, "Call Parking Called, lot: %d, timeout: %d, context: %s\n", lot, timeout, args.return_context);
00123 
00124    /* Now place the call to the extension */
00125 
00126    snprintf(buf, sizeof(buf), "%d", lot);
00127    oh.parent_channel = chan;
00128    oh.vars = ast_variable_new("_PARKEDAT", buf, "");
00129    dchan = __ast_request_and_dial(dialtech, AST_FORMAT_SLINEAR, args.dial, 30000, &outstate, chan->cid.cid_num, chan->cid.cid_name, &oh);
00130 
00131    if (dchan) {
00132       if (dchan->_state == AST_STATE_UP) {
00133          ast_verb(4, "Channel %s was answered.\n", dchan->name);
00134       } else {
00135          ast_verb(4, "Channel %s was never answered.\n", dchan->name);
00136          ast_log(LOG_WARNING, "PARK: Channel %s was never answered for the announce.\n", dchan->name);
00137          ast_hangup(dchan);
00138          return -1;
00139       }
00140    } else {
00141       ast_log(LOG_WARNING, "PARK: Unable to allocate announce channel.\n");
00142       return -1; 
00143    }
00144 
00145    ast_stopstream(dchan);
00146 
00147    /* now we have the call placed and are ready to play stuff to it */
00148 
00149    ast_verb(4, "Announce Template:%s\n", args.template);
00150 
00151    for (looptemp = 0; looptemp < ARRAY_LEN(tmp); looptemp++) {
00152       if ((tmp[looptemp] = strsep(&args.template, ":")) != NULL)
00153          continue;
00154       else
00155          break;
00156    }
00157 
00158    for (i = 0; i < looptemp; i++) {
00159       ast_verb(4, "Announce:%s\n", tmp[i]);
00160       if (!strcmp(tmp[i], "PARKED")) {
00161          ast_say_digits(dchan, lot, "", dchan->language);
00162       } else {
00163          dres = ast_streamfile(dchan, tmp[i], dchan->language);
00164          if (!dres) {
00165             dres = ast_waitstream(dchan, "");
00166          } else {
00167             ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n", tmp[i], dchan->name);
00168             dres = 0;
00169          }
00170       }
00171    }
00172 
00173    ast_stopstream(dchan);  
00174    ast_hangup(dchan);
00175    
00176    return res;
00177 }
00178 
00179 static int unload_module(void)
00180 {
00181    return ast_unregister_application(app);
00182 }
00183 
00184 static int load_module(void)
00185 {
00186    /* return ast_register_application(app, park_exec); */
00187    return ast_register_application(app, parkandannounce_exec, synopsis, descrip);
00188 }
00189 
00190 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Call Parking and Announce Application");

Generated on Wed Aug 18 22:33:41 2010 for Asterisk - the Open Source PBX by  doxygen 1.4.7