Wed Apr 6 11:29:38 2011

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: 276347 $")
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 /*** DOCUMENTATION
00047    <application name="ParkAndAnnounce" language="en_US">
00048       <synopsis>
00049          Park and Announce.
00050       </synopsis>
00051       <syntax>
00052          <parameter name="announce_template" required="true" argsep=":">
00053             <argument name="announce" required="true">
00054                <para>Colon-separated list of files to announce. The word
00055                <literal>PARKED</literal> will be replaced by a say_digits of the extension in which
00056                the call is parked.</para>
00057             </argument>
00058             <argument name="announce1" multiple="true" />
00059          </parameter>
00060          <parameter name="timeout" required="true">
00061             <para>Time in seconds before the call returns into the return
00062             context.</para>
00063          </parameter>
00064          <parameter name="dial" required="true">
00065             <para>The app_dial style resource to call to make the
00066             announcement. Console/dsp calls the console.</para>
00067          </parameter>
00068          <parameter name="return_context">
00069             <para>The goto-style label to jump the call back into after
00070             timeout. Default <literal>priority+1</literal>.</para>
00071          </parameter>
00072       </syntax>
00073       <description>
00074          <para>Park a call into the parkinglot and announce the call to another channel.</para>
00075          <para>The variable <variable>PARKEDAT</variable> will contain the parking extension
00076          into which the call was placed.  Use with the Local channel to allow the dialplan to make
00077          use of this information.</para>
00078       </description>
00079       <see-also>
00080          <ref type="application">Park</ref>
00081          <ref type="application">ParkedCall</ref>
00082       </see-also>
00083    </application>
00084  ***/
00085 
00086 static char *app = "ParkAndAnnounce";
00087 
00088 static int parkandannounce_exec(struct ast_channel *chan, const char *data)
00089 {
00090    int res = -1;
00091    int lot, timeout = 0, dres;
00092    char *dialtech, *tmp[100], buf[13];
00093    int looptemp, i;
00094    char *s;
00095 
00096    struct ast_channel *dchan;
00097    struct outgoing_helper oh = { 0, };
00098    int outstate;
00099    AST_DECLARE_APP_ARGS(args,
00100       AST_APP_ARG(template);
00101       AST_APP_ARG(timeout);
00102       AST_APP_ARG(dial);
00103       AST_APP_ARG(return_context);
00104    );
00105    if (ast_strlen_zero(data)) {
00106       ast_log(LOG_WARNING, "ParkAndAnnounce requires arguments: (announce:template|timeout|dial|[return_context])\n");
00107       return -1;
00108    }
00109   
00110    s = ast_strdupa(data);
00111    AST_STANDARD_APP_ARGS(args, s);
00112 
00113    if (args.timeout)
00114       timeout = atoi(args.timeout) * 1000;
00115 
00116    if (ast_strlen_zero(args.dial)) {
00117       ast_log(LOG_WARNING, "PARK: A dial resource must be specified i.e: Console/dsp or DAHDI/g1/5551212\n");
00118       return -1;
00119    }
00120 
00121    dialtech = strsep(&args.dial, "/");
00122    ast_verb(3, "Dial Tech,String: (%s,%s)\n", dialtech, args.dial);
00123 
00124    if (!ast_strlen_zero(args.return_context)) {
00125       ast_clear_flag(chan, AST_FLAG_IN_AUTOLOOP);
00126       ast_parseable_goto(chan, args.return_context);
00127    }
00128 
00129    ast_verb(3, "Return Context: (%s,%s,%d) ID: %s\n", chan->context, chan->exten,
00130       chan->priority,
00131       S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, ""));
00132    if (!ast_exists_extension(chan, chan->context, chan->exten, chan->priority,
00133       S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL))) {
00134       ast_verb(3, "Warning: Return Context Invalid, call will return to default|s\n");
00135    }
00136 
00137    /* we are using masq_park here to protect * from touching the channel once we park it.  If the channel comes out of timeout
00138    before we are done announcing and the channel is messed with, Kablooeee.  So we use Masq to prevent this.  */
00139 
00140    res = ast_masq_park_call(chan, NULL, timeout, &lot);
00141    if (res == -1)
00142       return res;
00143 
00144    ast_verb(3, "Call Parking Called, lot: %d, timeout: %d, context: %s\n", lot, timeout, args.return_context);
00145 
00146    /* Now place the call to the extension */
00147 
00148    snprintf(buf, sizeof(buf), "%d", lot);
00149    oh.parent_channel = chan;
00150    oh.vars = ast_variable_new("_PARKEDAT", buf, "");
00151    dchan = __ast_request_and_dial(dialtech, AST_FORMAT_SLINEAR, chan, args.dial, 30000,
00152       &outstate,
00153       S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL),
00154       S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL),
00155       &oh);
00156    if (dchan) {
00157       if (dchan->_state == AST_STATE_UP) {
00158          ast_verb(4, "Channel %s was answered.\n", dchan->name);
00159       } else {
00160          ast_verb(4, "Channel %s was never answered.\n", dchan->name);
00161          ast_log(LOG_WARNING, "PARK: Channel %s was never answered for the announce.\n", dchan->name);
00162          ast_hangup(dchan);
00163          return -1;
00164       }
00165    } else {
00166       ast_log(LOG_WARNING, "PARK: Unable to allocate announce channel.\n");
00167       return -1; 
00168    }
00169 
00170    ast_stopstream(dchan);
00171 
00172    /* now we have the call placed and are ready to play stuff to it */
00173 
00174    ast_verb(4, "Announce Template:%s\n", args.template);
00175 
00176    for (looptemp = 0; looptemp < ARRAY_LEN(tmp); looptemp++) {
00177       if ((tmp[looptemp] = strsep(&args.template, ":")) != NULL)
00178          continue;
00179       else
00180          break;
00181    }
00182 
00183    for (i = 0; i < looptemp; i++) {
00184       ast_verb(4, "Announce:%s\n", tmp[i]);
00185       if (!strcmp(tmp[i], "PARKED")) {
00186          ast_say_digits(dchan, lot, "", dchan->language);
00187       } else {
00188          dres = ast_streamfile(dchan, tmp[i], dchan->language);
00189          if (!dres) {
00190             dres = ast_waitstream(dchan, "");
00191          } else {
00192             ast_log(LOG_WARNING, "ast_streamfile of %s failed on %s\n", tmp[i], dchan->name);
00193             dres = 0;
00194          }
00195       }
00196    }
00197 
00198    ast_stopstream(dchan);  
00199    ast_hangup(dchan);
00200    
00201    return res;
00202 }
00203 
00204 static int unload_module(void)
00205 {
00206    return ast_unregister_application(app);
00207 }
00208 
00209 static int load_module(void)
00210 {
00211    /* return ast_register_application(app, park_exec); */
00212    return ast_register_application_xml(app, parkandannounce_exec);
00213 }
00214 
00215 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Call Parking and Announce Application");

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