Mon Sep 20 2010 00:19:43

Asterisk developer's documentation


app_dial.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2008, Digium, Inc.
00005  *
00006  * Mark Spencer <markster@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*! \file
00020  *
00021  * \brief dial() & retrydial() - Trivial application to dial a channel and send an URL on answer
00022  *
00023  * \author Mark Spencer <markster@digium.com>
00024  *
00025  * \ingroup applications
00026  */
00027 
00028 /*** MODULEINFO
00029    <depend>chan_local</depend>
00030  ***/
00031 
00032 
00033 #include "asterisk.h"
00034 
00035 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 255505 $")
00036 
00037 #include <sys/time.h>
00038 #include <sys/signal.h>
00039 #include <sys/stat.h>
00040 #include <netinet/in.h>
00041 
00042 #include "asterisk/paths.h" /* use ast_config_AST_DATA_DIR */
00043 #include "asterisk/lock.h"
00044 #include "asterisk/file.h"
00045 #include "asterisk/channel.h"
00046 #include "asterisk/pbx.h"
00047 #include "asterisk/module.h"
00048 #include "asterisk/translate.h"
00049 #include "asterisk/say.h"
00050 #include "asterisk/config.h"
00051 #include "asterisk/features.h"
00052 #include "asterisk/musiconhold.h"
00053 #include "asterisk/callerid.h"
00054 #include "asterisk/utils.h"
00055 #include "asterisk/app.h"
00056 #include "asterisk/causes.h"
00057 #include "asterisk/rtp.h"
00058 #include "asterisk/cdr.h"
00059 #include "asterisk/manager.h"
00060 #include "asterisk/privacy.h"
00061 #include "asterisk/stringfields.h"
00062 #include "asterisk/global_datastores.h"
00063 #include "asterisk/dsp.h"
00064 
00065 /*** DOCUMENTATION
00066    <application name="Dial" language="en_US">
00067       <synopsis>
00068          Attempt to connect to another device or endpoint and bridge the call.
00069       </synopsis>
00070       <syntax>
00071          <parameter name="Technology/Resource" required="true" argsep="&amp;">
00072             <argument name="Technology/Resource" required="true">
00073                <para>Specification of the device(s) to dial.  These must be in the format of
00074                <literal>Technology/Resource</literal>, where <replaceable>Technology</replaceable>
00075                represents a particular channel driver, and <replaceable>Resource</replaceable>
00076                represents a resource available to that particular channel driver.</para>
00077             </argument>
00078             <argument name="Technology2/Resource2" required="false" multiple="true">
00079                <para>Optional extra devices to dial in parallel</para>
00080                <para>If you need more then one enter them as
00081                Technology2/Resource2&amp;Technology3/Resourse3&amp;.....</para>
00082             </argument>
00083          </parameter>
00084          <parameter name="timeout" required="false">
00085             <para>Specifies the number of seconds we attempt to dial the specified devices</para>
00086             <para>If not specified, this defaults to 136 years.</para>
00087          </parameter>
00088          <parameter name="options" required="false">
00089             <optionlist>
00090             <option name="A">
00091                <argument name="x" required="true">
00092                   <para>The file to play to the called party</para>
00093                </argument>
00094                <para>Play an announcement to the called party, where <replaceable>x</replaceable> is the prompt to be played</para>
00095             </option>
00096             <option name="C">
00097                <para>Reset the call detail record (CDR) for this call.</para>
00098             </option>
00099             <option name="c">
00100                <para>If the Dial() application cancels this call, always set the flag to tell the channel
00101                driver that the call is answered elsewhere.</para>
00102             </option>
00103             <option name="d">
00104                <para>Allow the calling user to dial a 1 digit extension while waiting for
00105                a call to be answered. Exit to that extension if it exists in the
00106                current context, or the context defined in the <variable>EXITCONTEXT</variable> variable,
00107                if it exists.</para>
00108             </option>
00109             <option name="D" argsep=":">
00110                <argument name="called" />
00111                <argument name="calling" />
00112                <para>Send the specified DTMF strings <emphasis>after</emphasis> the called
00113                party has answered, but before the call gets bridged. The 
00114                <replaceable>called</replaceable> DTMF string is sent to the called party, and the 
00115                <replaceable>calling</replaceable> DTMF string is sent to the calling party. Both arguments 
00116                can be used alone.</para>
00117             </option>
00118             <option name="e">
00119                <para>Execute the <literal>h</literal> extension for peer after the call ends</para>
00120             </option>
00121             <option name="f">
00122                <para>Force the callerid of the <emphasis>calling</emphasis> channel to be set as the
00123                extension associated with the channel using a dialplan <literal>hint</literal>.
00124                For example, some PSTNs do not allow CallerID to be set to anything
00125                other than the number assigned to the caller.</para>
00126             </option>
00127             <option name="F" argsep="^">
00128                <argument name="context" required="false" />
00129                <argument name="exten" required="false" />
00130                <argument name="priority" required="true" />
00131                <para>When the caller hangs up, transfer the called party
00132                to the specified destination and continue execution at that location.</para>
00133             </option>
00134             <option name="g">
00135                <para>Proceed with dialplan execution at the next priority in the current extension if the
00136                destination channel hangs up.</para>
00137             </option>
00138             <option name="G" argsep="^">
00139                <argument name="context" required="false" />
00140                <argument name="exten" required="false" />
00141                <argument name="priority" required="true" />
00142                <para>If the call is answered, transfer the calling party to
00143                the specified <replaceable>priority</replaceable> and the called party to the specified 
00144                <replaceable>priority</replaceable> plus one.</para>
00145                <note>
00146                   <para>You cannot use any additional action post answer options in conjunction with this option.</para>
00147                </note>
00148             </option>
00149             <option name="h">
00150                <para>Allow the called party to hang up by sending the <literal>*</literal> DTMF digit.</para>
00151             </option>
00152             <option name="H">
00153                <para>Allow the calling party to hang up by hitting the <literal>*</literal> DTMF digit.</para>
00154             </option>
00155             <option name="i">
00156                <para>Asterisk will ignore any forwarding requests it may receive on this dial attempt.</para>
00157             </option>
00158             <option name="k">
00159                <para>Allow the called party to enable parking of the call by sending
00160                the DTMF sequence defined for call parking in <filename>features.conf</filename>.</para>
00161             </option>
00162             <option name="K">
00163                <para>Allow the calling party to enable parking of the call by sending
00164                the DTMF sequence defined for call parking in <filename>features.conf</filename>.</para>
00165             </option>
00166             <option name="L" argsep=":">
00167                <argument name="x" required="true">
00168                   <para>Maximum call time, in milliseconds</para>
00169                </argument>
00170                <argument name="y">
00171                   <para>Warning time, in milliseconds</para>
00172                </argument>
00173                <argument name="z">
00174                   <para>Repeat time, in milliseconds</para>
00175                </argument>
00176                <para>Limit the call to <replaceable>x</replaceable> milliseconds. Play a warning when <replaceable>y</replaceable> milliseconds are
00177                left. Repeat the warning every <replaceable>z</replaceable> milliseconds until time expires.</para>
00178                <para>This option is affected by the following variables:</para>
00179                <variablelist>
00180                   <variable name="LIMIT_PLAYAUDIO_CALLER">
00181                      <value name="yes" default="true" />
00182                      <value name="no" />
00183                      <para>If set, this variable causes Asterisk to play the prompts to the caller.</para>
00184                   </variable>
00185                   <variable name="LIMIT_PLAYAUDIO_CALLEE">
00186                      <value name="yes" />
00187                      <value name="no" default="true"/>
00188                      <para>If set, this variable causes Asterisk to play the prompts to the callee.</para>
00189                   </variable>
00190                   <variable name="LIMIT_TIMEOUT_FILE">
00191                      <value name="filename"/>
00192                      <para>If specified, <replaceable>filename</replaceable> specifies the sound prompt to play when the timeout is reached.
00193                      If not set, the time remaining will be announced.</para>
00194                   </variable>
00195                   <variable name="LIMIT_CONNECT_FILE">
00196                      <value name="filename"/>
00197                      <para>If specified, <replaceable>filename</replaceable> specifies the sound prompt to play when the call begins.
00198                      If not set, the time remaining will be announced.</para>
00199                   </variable>
00200                   <variable name="LIMIT_WARNING_FILE">
00201                      <value name="filename"/>
00202                      <para>If specified, <replaceable>filename</replaceable> specifies the sound prompt to play as
00203                      a warning when time <replaceable>x</replaceable> is reached. If not set, the time remaining will be announced.</para>
00204                   </variable>
00205                </variablelist>
00206             </option>
00207             <option name="m">
00208                <argument name="class" required="false"/>
00209                <para>Provide hold music to the calling party until a requested
00210                channel answers. A specific music on hold <replaceable>class</replaceable>
00211                (as defined in <filename>musiconhold.conf</filename>) can be specified.</para>
00212             </option>
00213             <option name="M" argsep="^">
00214                <argument name="macro" required="true">
00215                   <para>Name of the macro that should be executed.</para>
00216                </argument>
00217                <argument name="arg" multiple="true">
00218                   <para>Macro arguments</para>
00219                </argument>
00220                <para>Execute the specified <replaceable>macro</replaceable> for the <emphasis>called</emphasis> channel 
00221                before connecting to the calling channel. Arguments can be specified to the Macro
00222                using <literal>^</literal> as a delimiter. The macro can set the variable
00223                <variable>MACRO_RESULT</variable> to specify the following actions after the macro is
00224                finished executing:</para>
00225                <variablelist>
00226                   <variable name="MACRO_RESULT">
00227                      <para>If set, this action will be taken after the macro finished executing.</para>
00228                      <value name="ABORT">
00229                         Hangup both legs of the call
00230                      </value>
00231                      <value name="CONGESTION">
00232                         Behave as if line congestion was encountered
00233                      </value>
00234                      <value name="BUSY">
00235                         Behave as if a busy signal was encountered
00236                      </value>
00237                      <value name="CONTINUE">
00238                         Hangup the called party and allow the calling party to continue dialplan execution at the next priority
00239                      </value>
00240                      <!-- TODO: Fix this syntax up, once we've figured out how to specify the GOTO syntax -->
00241                      <value name="GOTO:&lt;context&gt;^&lt;exten&gt;^&lt;priority&gt;">
00242                         Transfer the call to the specified destination.
00243                      </value>
00244                   </variable>
00245                </variablelist>
00246                <note>
00247                   <para>You cannot use any additional action post answer options in conjunction
00248                   with this option. Also, pbx services are not run on the peer (called) channel,
00249                   so you will not be able to set timeouts via the TIMEOUT() function in this macro.</para>
00250                </note>
00251                <warning><para>Be aware of the limitations that macros have, specifically with regards to use of
00252                the <literal>WaitExten</literal> application. For more information, see the documentation for
00253                Macro()</para></warning>
00254             </option>
00255             <option name="n">
00256                     <argument name="delete">
00257                        <para>With <replaceable>delete</replaceable> either not specified or set to <literal>0</literal>,
00258                   the recorded introduction will not be deleted if the caller hangs up while the remote party has not
00259                   yet answered.</para>
00260                   <para>With <replaceable>delete</replaceable> set to <literal>1</literal>, the introduction will
00261                   always be deleted.</para>
00262                </argument>
00263                <para>This option is a modifier for the call screening/privacy mode. (See the 
00264                <literal>p</literal> and <literal>P</literal> options.) It specifies
00265                that no introductions are to be saved in the <directory>priv-callerintros</directory>
00266                directory.</para>
00267             </option>
00268             <option name="N">
00269                <para>This option is a modifier for the call screening/privacy mode. It specifies
00270                that if Caller*ID is present, do not screen the call.</para>
00271             </option>
00272             <option name="o">
00273                <para>Specify that the Caller*ID that was present on the <emphasis>calling</emphasis> channel
00274                be set as the Caller*ID on the <emphasis>called</emphasis> channel. This was the
00275                behavior of Asterisk 1.0 and earlier.</para>
00276             </option>
00277             <option name="O">
00278                <argument name="mode">
00279                   <para>With <replaceable>mode</replaceable> either not specified or set to <literal>1</literal>,
00280                   the originator hanging up will cause the phone to ring back immediately.</para>
00281                   <para>With <replaceable>mode</replaceable> set to <literal>2</literal>, when the operator 
00282                   flashes the trunk, it will ring their phone back.</para>
00283                </argument>
00284                <para>Enables <emphasis>operator services</emphasis> mode.  This option only
00285                works when bridging a DAHDI channel to another DAHDI channel
00286                only. if specified on non-DAHDI interfaces, it will be ignored.
00287                When the destination answers (presumably an operator services
00288                station), the originator no longer has control of their line.
00289                They may hang up, but the switch will not release their line
00290                until the destination party (the operator) hangs up.</para>
00291             </option>
00292             <option name="p">
00293                <para>This option enables screening mode. This is basically Privacy mode
00294                without memory.</para>
00295             </option>
00296             <option name="P">
00297                <argument name="x" />
00298                <para>Enable privacy mode. Use <replaceable>x</replaceable> as the family/key in the AstDB database if
00299                it is provided. The current extension is used if a database family/key is not specified.</para>
00300             </option>
00301             <option name="r">
00302                <para>Indicate ringing to the calling party, even if the called party isn't actually ringing. Pass no audio to the calling
00303                party until the called channel has answered.</para>
00304             </option>
00305             <option name="S">
00306                <argument name="x" required="true" />
00307                <para>Hang up the call <replaceable>x</replaceable> seconds <emphasis>after</emphasis> the called party has
00308                answered the call.</para>
00309             </option>
00310             <option name="t">
00311                <para>Allow the called party to transfer the calling party by sending the
00312                DTMF sequence defined in <filename>features.conf</filename>. This setting does not perform policy enforcement on
00313                transfers initiated by other methods.</para>
00314             </option>
00315             <option name="T">
00316                <para>Allow the calling party to transfer the called party by sending the
00317                DTMF sequence defined in <filename>features.conf</filename>. This setting does not perform policy enforcement on
00318                transfers initiated by other methods.</para>
00319             </option>
00320             <option name="U" argsep="^">
00321                <argument name="x" required="true">
00322                   <para>Name of the subroutine to execute via Gosub</para>
00323                </argument>
00324                <argument name="arg" multiple="true" required="false">
00325                   <para>Arguments for the Gosub routine</para>
00326                </argument>
00327                <para>Execute via Gosub the routine <replaceable>x</replaceable> for the <emphasis>called</emphasis> channel before connecting
00328                to the calling channel. Arguments can be specified to the Gosub
00329                using <literal>^</literal> as a delimiter. The Gosub routine can set the variable
00330                <variable>GOSUB_RESULT</variable> to specify the following actions after the Gosub returns.</para>
00331                <variablelist>
00332                   <variable name="GOSUB_RESULT">
00333                      <value name="ABORT">
00334                         Hangup both legs of the call.
00335                      </value>
00336                      <value name="CONGESTION">
00337                         Behave as if line congestion was encountered.
00338                      </value>
00339                      <value name="BUSY">
00340                         Behave as if a busy signal was encountered.
00341                      </value>
00342                      <value name="CONTINUE">
00343                         Hangup the called party and allow the calling party
00344                         to continue dialplan execution at the next priority.
00345                      </value>
00346                      <!-- TODO: Fix this syntax up, once we've figured out how to specify the GOTO syntax -->
00347                      <value name="GOTO:&lt;context&gt;^&lt;exten&gt;^&lt;priority&gt;">
00348                         Transfer the call to the specified priority. Optionally, an extension, or
00349                         extension and priority can be specified.
00350                      </value>
00351                   </variable>
00352                </variablelist>
00353                <note>
00354                   <para>You cannot use any additional action post answer options in conjunction
00355                   with this option. Also, pbx services are not run on the peer (called) channel,
00356                   so you will not be able to set timeouts via the TIMEOUT() function in this routine.</para>
00357                </note>
00358             </option>
00359             <option name="w">
00360                <para>Allow the called party to enable recording of the call by sending
00361                the DTMF sequence defined for one-touch recording in <filename>features.conf</filename>.</para>
00362             </option>
00363             <option name="W">
00364                <para>Allow the calling party to enable recording of the call by sending
00365                the DTMF sequence defined for one-touch recording in <filename>features.conf</filename>.</para>
00366             </option>
00367             <option name="x">
00368                <para>Allow the called party to enable recording of the call by sending
00369                the DTMF sequence defined for one-touch automixmonitor in <filename>features.conf</filename>.</para>
00370             </option>
00371             <option name="X">
00372                <para>Allow the calling party to enable recording of the call by sending
00373                the DTMF sequence defined for one-touch automixmonitor in <filename>features.conf</filename>.</para>
00374             </option>
00375             </optionlist>
00376          </parameter>
00377          <parameter name="URL">
00378             <para>The optional URL will be sent to the called party if the channel driver supports it.</para>
00379          </parameter>
00380       </syntax>
00381       <description>
00382          <para>This application will place calls to one or more specified channels. As soon
00383          as one of the requested channels answers, the originating channel will be
00384          answered, if it has not already been answered. These two channels will then
00385          be active in a bridged call. All other channels that were requested will then
00386          be hung up.</para>
00387 
00388          <para>Unless there is a timeout specified, the Dial application will wait
00389          indefinitely until one of the called channels answers, the user hangs up, or
00390          if all of the called channels are busy or unavailable. Dialplan executing will
00391          continue if no requested channels can be called, or if the timeout expires.
00392          This application will report normal termination if the originating channel
00393          hangs up, or if the call is bridged and either of the parties in the bridge
00394          ends the call.</para>
00395 
00396          <para>If the <variable>OUTBOUND_GROUP</variable> variable is set, all peer channels created by this
00397          application will be put into that group (as in Set(GROUP()=...).
00398          If the <variable>OUTBOUND_GROUP_ONCE</variable> variable is set, all peer channels created by this
00399          application will be put into that group (as in Set(GROUP()=...). Unlike OUTBOUND_GROUP,
00400          however, the variable will be unset after use.</para>
00401 
00402          <para>This application sets the following channel variables:</para>
00403          <variablelist>
00404             <variable name="DIALEDTIME">
00405                <para>This is the time from dialing a channel until when it is disconnected.</para>
00406             </variable>
00407             <variable name="ANSWEREDTIME">
00408                <para>This is the amount of time for actual call.</para>
00409             </variable>
00410             <variable name="DIALSTATUS">
00411                <para>This is the status of the call</para>
00412                <value name="CHANUNAVAIL" />
00413                <value name="CONGESTION" />
00414                <value name="NOANSWER" />
00415                <value name="BUSY" />
00416                <value name="ANSWER" />
00417                <value name="CANCEL" />
00418                <value name="DONTCALL">
00419                   For the Privacy and Screening Modes.
00420                   Will be set if the called party chooses to send the calling party to the 'Go Away' script.
00421                </value>
00422                <value name="TORTURE">
00423                   For the Privacy and Screening Modes.
00424                   Will be set if the called party chooses to send the calling party to the 'torture' script.
00425                </value>
00426                <value name="INVALIDARGS" />
00427             </variable>
00428          </variablelist>
00429       </description>
00430    </application>
00431    <application name="RetryDial" language="en_US">
00432       <synopsis>
00433          Place a call, retrying on failure allowing an optional exit extension.
00434       </synopsis>
00435       <syntax>
00436          <parameter name="announce" required="true">
00437             <para>Filename of sound that will be played when no channel can be reached</para>
00438          </parameter>
00439          <parameter name="sleep" required="true">
00440             <para>Number of seconds to wait after a dial attempt failed before a new attempt is made</para>
00441          </parameter>
00442          <parameter name="retries" required="true">
00443             <para>Number of retries</para>
00444             <para>When this is reached flow will continue at the next priority in the dialplan</para>
00445          </parameter>
00446          <parameter name="dialargs" required="true">
00447             <para>Same format as arguments provided to the Dial application</para>
00448          </parameter>
00449       </syntax>
00450       <description>
00451          <para>This application will attempt to place a call using the normal Dial application.
00452          If no channel can be reached, the <replaceable>announce</replaceable> file will be played.
00453          Then, it will wait <replaceable>sleep</replaceable> number of seconds before retrying the call.
00454          After <replaceable>retries</replaceable> number of attempts, the calling channel will continue at the next priority in the dialplan.
00455          If the <replaceable>retries</replaceable> setting is set to 0, this application will retry endlessly.
00456          While waiting to retry a call, a 1 digit extension may be dialed. If that
00457          extension exists in either the context defined in <variable>EXITCONTEXT</variable> or the current
00458          one, The call will jump to that extension immediately.
00459          The <replaceable>dialargs</replaceable> are specified in the same format that arguments are provided
00460          to the Dial application.</para>
00461       </description>
00462    </application>
00463  ***/
00464 
00465 static char *app = "Dial";
00466 static char *rapp = "RetryDial";
00467 
00468 enum {
00469    OPT_ANNOUNCE =          (1 << 0),
00470    OPT_RESETCDR =          (1 << 1),
00471    OPT_DTMF_EXIT =         (1 << 2),
00472    OPT_SENDDTMF =          (1 << 3),
00473    OPT_FORCECLID =         (1 << 4),
00474    OPT_GO_ON =             (1 << 5),
00475    OPT_CALLEE_HANGUP =     (1 << 6),
00476    OPT_CALLER_HANGUP =     (1 << 7),
00477    OPT_DURATION_LIMIT =    (1 << 9),
00478    OPT_MUSICBACK =         (1 << 10),
00479    OPT_CALLEE_MACRO =      (1 << 11),
00480    OPT_SCREEN_NOINTRO =    (1 << 12),
00481    OPT_SCREEN_NOCLID =     (1 << 13),
00482    OPT_ORIGINAL_CLID =     (1 << 14),
00483    OPT_SCREENING =         (1 << 15),
00484    OPT_PRIVACY =           (1 << 16),
00485    OPT_RINGBACK =          (1 << 17),
00486    OPT_DURATION_STOP =     (1 << 18),
00487    OPT_CALLEE_TRANSFER =   (1 << 19),
00488    OPT_CALLER_TRANSFER =   (1 << 20),
00489    OPT_CALLEE_MONITOR =    (1 << 21),
00490    OPT_CALLER_MONITOR =    (1 << 22),
00491    OPT_GOTO =              (1 << 23),
00492    OPT_OPERMODE =          (1 << 24),
00493    OPT_CALLEE_PARK =       (1 << 25),
00494    OPT_CALLER_PARK =       (1 << 26),
00495    OPT_IGNORE_FORWARDING = (1 << 27),
00496    OPT_CALLEE_GOSUB =      (1 << 28),
00497    OPT_CALLEE_MIXMONITOR = (1 << 29),
00498    OPT_CALLER_MIXMONITOR = (1 << 30),
00499 };
00500 
00501 #define DIAL_STILLGOING      (1 << 31)
00502 #define DIAL_NOFORWARDHTML   ((uint64_t)1 << 32) /* flags are now 64 bits, so keep it up! */
00503 #define OPT_CANCEL_ELSEWHERE ((uint64_t)1 << 33)
00504 #define OPT_PEER_H           ((uint64_t)1 << 34)
00505 #define OPT_CALLEE_GO_ON     ((uint64_t)1 << 35)
00506 
00507 enum {
00508    OPT_ARG_ANNOUNCE = 0,
00509    OPT_ARG_SENDDTMF,
00510    OPT_ARG_GOTO,
00511    OPT_ARG_DURATION_LIMIT,
00512    OPT_ARG_MUSICBACK,
00513    OPT_ARG_CALLEE_MACRO,
00514    OPT_ARG_CALLEE_GOSUB,
00515    OPT_ARG_CALLEE_GO_ON,
00516    OPT_ARG_PRIVACY,
00517    OPT_ARG_DURATION_STOP,
00518    OPT_ARG_OPERMODE,
00519    OPT_ARG_SCREEN_NOINTRO,
00520    /* note: this entry _MUST_ be the last one in the enum */
00521    OPT_ARG_ARRAY_SIZE,
00522 };
00523 
00524 AST_APP_OPTIONS(dial_exec_options, BEGIN_OPTIONS
00525    AST_APP_OPTION_ARG('A', OPT_ANNOUNCE, OPT_ARG_ANNOUNCE),
00526    AST_APP_OPTION('C', OPT_RESETCDR),
00527    AST_APP_OPTION('c', OPT_CANCEL_ELSEWHERE),
00528    AST_APP_OPTION('d', OPT_DTMF_EXIT),
00529    AST_APP_OPTION_ARG('D', OPT_SENDDTMF, OPT_ARG_SENDDTMF),
00530    AST_APP_OPTION('e', OPT_PEER_H),
00531    AST_APP_OPTION('f', OPT_FORCECLID),
00532    AST_APP_OPTION_ARG('F', OPT_CALLEE_GO_ON, OPT_ARG_CALLEE_GO_ON),
00533    AST_APP_OPTION('g', OPT_GO_ON),
00534    AST_APP_OPTION_ARG('G', OPT_GOTO, OPT_ARG_GOTO),
00535    AST_APP_OPTION('h', OPT_CALLEE_HANGUP),
00536    AST_APP_OPTION('H', OPT_CALLER_HANGUP),
00537    AST_APP_OPTION('i', OPT_IGNORE_FORWARDING),
00538    AST_APP_OPTION('k', OPT_CALLEE_PARK),
00539    AST_APP_OPTION('K', OPT_CALLER_PARK),
00540    AST_APP_OPTION_ARG('L', OPT_DURATION_LIMIT, OPT_ARG_DURATION_LIMIT),
00541    AST_APP_OPTION_ARG('m', OPT_MUSICBACK, OPT_ARG_MUSICBACK),
00542    AST_APP_OPTION_ARG('M', OPT_CALLEE_MACRO, OPT_ARG_CALLEE_MACRO),
00543    AST_APP_OPTION_ARG('n', OPT_SCREEN_NOINTRO, OPT_ARG_SCREEN_NOINTRO),
00544    AST_APP_OPTION('N', OPT_SCREEN_NOCLID),
00545    AST_APP_OPTION('o', OPT_ORIGINAL_CLID),
00546    AST_APP_OPTION_ARG('O', OPT_OPERMODE, OPT_ARG_OPERMODE),
00547    AST_APP_OPTION('p', OPT_SCREENING),
00548    AST_APP_OPTION_ARG('P', OPT_PRIVACY, OPT_ARG_PRIVACY),
00549    AST_APP_OPTION('r', OPT_RINGBACK),
00550    AST_APP_OPTION_ARG('S', OPT_DURATION_STOP, OPT_ARG_DURATION_STOP),
00551    AST_APP_OPTION('t', OPT_CALLEE_TRANSFER),
00552    AST_APP_OPTION('T', OPT_CALLER_TRANSFER),
00553    AST_APP_OPTION_ARG('U', OPT_CALLEE_GOSUB, OPT_ARG_CALLEE_GOSUB),
00554    AST_APP_OPTION('w', OPT_CALLEE_MONITOR),
00555    AST_APP_OPTION('W', OPT_CALLER_MONITOR),
00556    AST_APP_OPTION('x', OPT_CALLEE_MIXMONITOR),
00557    AST_APP_OPTION('X', OPT_CALLER_MIXMONITOR),
00558 END_OPTIONS );
00559 
00560 #define CAN_EARLY_BRIDGE(flags,chan,peer) (!ast_test_flag64(flags, OPT_CALLEE_HANGUP | \
00561    OPT_CALLER_HANGUP | OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER | \
00562    OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR | OPT_CALLEE_PARK |  \
00563    OPT_CALLER_PARK | OPT_ANNOUNCE | OPT_CALLEE_MACRO | OPT_CALLEE_GOSUB) && \
00564    !chan->audiohooks && !peer->audiohooks)
00565 
00566 /*
00567  * The list of active channels
00568  */
00569 struct chanlist {
00570    struct chanlist *next;
00571    struct ast_channel *chan;
00572    uint64_t flags;
00573 };
00574 
00575 
00576 static void hanguptree(struct chanlist *outgoing, struct ast_channel *exception, int answered_elsewhere)
00577 {
00578    /* Hang up a tree of stuff */
00579    struct chanlist *oo;
00580    while (outgoing) {
00581       /* Hangup any existing lines we have open */
00582       if (outgoing->chan && (outgoing->chan != exception)) {
00583          if (answered_elsewhere) {
00584             /* The flag is used for local channel inheritance and stuff */
00585             ast_set_flag(outgoing->chan, AST_FLAG_ANSWERED_ELSEWHERE);
00586             /* This is for the channel drivers */
00587             outgoing->chan->hangupcause = AST_CAUSE_ANSWERED_ELSEWHERE;
00588          }
00589          ast_hangup(outgoing->chan);
00590       }
00591       oo = outgoing;
00592       outgoing = outgoing->next;
00593       ast_free(oo);
00594    }
00595 }
00596 
00597 #define AST_MAX_WATCHERS 256
00598 
00599 /*
00600  * argument to handle_cause() and other functions.
00601  */
00602 struct cause_args {
00603    struct ast_channel *chan;
00604    int busy;
00605    int congestion;
00606    int nochan;
00607 };
00608 
00609 static void handle_cause(int cause, struct cause_args *num)
00610 {
00611    struct ast_cdr *cdr = num->chan->cdr;
00612 
00613    switch(cause) {
00614    case AST_CAUSE_BUSY:
00615       if (cdr)
00616          ast_cdr_busy(cdr);
00617       num->busy++;
00618       break;
00619 
00620    case AST_CAUSE_CONGESTION:
00621       if (cdr)
00622          ast_cdr_failed(cdr);
00623       num->congestion++;
00624       break;
00625 
00626    case AST_CAUSE_NO_ROUTE_DESTINATION:
00627    case AST_CAUSE_UNREGISTERED:
00628       if (cdr)
00629          ast_cdr_failed(cdr);
00630       num->nochan++;
00631       break;
00632 
00633    case AST_CAUSE_NO_ANSWER:
00634       if (cdr) {
00635          ast_cdr_noanswer(cdr);
00636       }
00637       break;
00638    case AST_CAUSE_NORMAL_CLEARING:
00639       break;
00640 
00641    default:
00642       num->nochan++;
00643       break;
00644    }
00645 }
00646 
00647 /* free the buffer if allocated, and set the pointer to the second arg */
00648 #define S_REPLACE(s, new_val)    \
00649    do {           \
00650       if (s)         \
00651          ast_free(s);   \
00652       s = (new_val);    \
00653    } while (0)
00654 
00655 static int onedigit_goto(struct ast_channel *chan, const char *context, char exten, int pri)
00656 {
00657    char rexten[2] = { exten, '\0' };
00658 
00659    if (context) {
00660       if (!ast_goto_if_exists(chan, context, rexten, pri))
00661          return 1;
00662    } else {
00663       if (!ast_goto_if_exists(chan, chan->context, rexten, pri))
00664          return 1;
00665       else if (!ast_strlen_zero(chan->macrocontext)) {
00666          if (!ast_goto_if_exists(chan, chan->macrocontext, rexten, pri))
00667             return 1;
00668       }
00669    }
00670    return 0;
00671 }
00672 
00673 
00674 static const char *get_cid_name(char *name, int namelen, struct ast_channel *chan)
00675 {
00676    const char *context = S_OR(chan->macrocontext, chan->context);
00677    const char *exten = S_OR(chan->macroexten, chan->exten);
00678 
00679    return ast_get_hint(NULL, 0, name, namelen, chan, context, exten) ? name : "";
00680 }
00681 
00682 static void senddialevent(struct ast_channel *src, struct ast_channel *dst, const char *dialstring)
00683 {
00684    manager_event(EVENT_FLAG_CALL, "Dial",
00685       "SubEvent: Begin\r\n"
00686       "Channel: %s\r\n"
00687       "Destination: %s\r\n"
00688       "CallerIDNum: %s\r\n"
00689       "CallerIDName: %s\r\n"
00690       "UniqueID: %s\r\n"
00691       "DestUniqueID: %s\r\n"
00692       "Dialstring: %s\r\n",
00693       src->name, dst->name, S_OR(src->cid.cid_num, "<unknown>"),
00694       S_OR(src->cid.cid_name, "<unknown>"), src->uniqueid,
00695       dst->uniqueid, dialstring ? dialstring : "");
00696 }
00697 
00698 static void senddialendevent(const struct ast_channel *src, const char *dialstatus)
00699 {
00700    manager_event(EVENT_FLAG_CALL, "Dial",
00701       "SubEvent: End\r\n"
00702       "Channel: %s\r\n"
00703       "UniqueID: %s\r\n"
00704       "DialStatus: %s\r\n",
00705       src->name, src->uniqueid, dialstatus);
00706 }
00707 
00708 /*!
00709  * helper function for wait_for_answer()
00710  *
00711  * XXX this code is highly suspicious, as it essentially overwrites
00712  * the outgoing channel without properly deleting it.
00713  */
00714 static void do_forward(struct chanlist *o,
00715    struct cause_args *num, struct ast_flags64 *peerflags, int single)
00716 {
00717    char tmpchan[256];
00718    struct ast_channel *original = o->chan;
00719    struct ast_channel *c = o->chan; /* the winner */
00720    struct ast_channel *in = num->chan; /* the input channel */
00721    char *stuff;
00722    char *tech;
00723    int cause;
00724 
00725    ast_copy_string(tmpchan, c->call_forward, sizeof(tmpchan));
00726    if ((stuff = strchr(tmpchan, '/'))) {
00727       *stuff++ = '\0';
00728       tech = tmpchan;
00729    } else {
00730       const char *forward_context;
00731       ast_channel_lock(c);
00732       forward_context = pbx_builtin_getvar_helper(c, "FORWARD_CONTEXT");
00733       if (ast_strlen_zero(forward_context)) {
00734          forward_context = NULL;
00735       }
00736       snprintf(tmpchan, sizeof(tmpchan), "%s@%s", c->call_forward, forward_context ? forward_context : c->context);
00737       ast_channel_unlock(c);
00738       stuff = tmpchan;
00739       tech = "Local";
00740    }
00741    /* Before processing channel, go ahead and check for forwarding */
00742    ast_verb(3, "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, c->name);
00743    /* If we have been told to ignore forwards, just set this channel to null and continue processing extensions normally */
00744    if (ast_test_flag64(peerflags, OPT_IGNORE_FORWARDING)) {
00745       ast_verb(3, "Forwarding %s to '%s/%s' prevented.\n", in->name, tech, stuff);
00746       c = o->chan = NULL;
00747       cause = AST_CAUSE_BUSY;
00748    } else {
00749       /* Setup parameters */
00750       c = o->chan = ast_request(tech, in->nativeformats, stuff, &cause);
00751       if (c) {
00752          if (single)
00753             ast_channel_make_compatible(o->chan, in);
00754          ast_channel_inherit_variables(in, o->chan);
00755          ast_channel_datastore_inherit(in, o->chan);
00756       } else
00757          ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause);
00758    }
00759    if (!c) {
00760       ast_clear_flag64(o, DIAL_STILLGOING);
00761       handle_cause(cause, num);
00762       ast_hangup(original);
00763    } else {
00764       char *new_cid_num, *new_cid_name;
00765       struct ast_channel *src;
00766 
00767       if (CAN_EARLY_BRIDGE(peerflags, c, in)) {
00768          ast_rtp_make_compatible(c, in, single);
00769       }
00770       if (ast_test_flag64(o, OPT_FORCECLID)) {
00771          new_cid_num = ast_strdup(S_OR(in->macroexten, in->exten));
00772          new_cid_name = NULL; /* XXX no name ? */
00773          src = c; /* XXX possible bug in previous code, which used 'winner' ? it may have changed */
00774       } else {
00775          new_cid_num = ast_strdup(in->cid.cid_num);
00776          new_cid_name = ast_strdup(in->cid.cid_name);
00777          src = in;
00778       }
00779       ast_string_field_set(c, accountcode, src->accountcode);
00780       c->cdrflags = src->cdrflags;
00781       S_REPLACE(c->cid.cid_num, new_cid_num);
00782       S_REPLACE(c->cid.cid_name, new_cid_name);
00783 
00784       if (in->cid.cid_ani) { /* XXX or maybe unconditional ? */
00785          S_REPLACE(c->cid.cid_ani, ast_strdup(in->cid.cid_ani));
00786       }
00787       S_REPLACE(c->cid.cid_rdnis, ast_strdup(S_OR(in->macroexten, in->exten)));
00788       if (ast_call(c, tmpchan, 0)) {
00789          ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
00790          ast_clear_flag64(o, DIAL_STILLGOING);
00791          ast_hangup(original);
00792          ast_hangup(c);
00793          c = o->chan = NULL;
00794          num->nochan++;
00795       } else {
00796          senddialevent(in, c, stuff);
00797          /* After calling, set callerid to extension */
00798          if (!ast_test_flag64(peerflags, OPT_ORIGINAL_CLID)) {
00799             char cidname[AST_MAX_EXTENSION] = "";
00800             ast_set_callerid(c, S_OR(in->macroexten, in->exten), get_cid_name(cidname, sizeof(cidname), in), NULL);
00801          }
00802          /* Hangup the original channel now, in case we needed it */
00803          ast_hangup(original);
00804       }
00805       if (single) {
00806          ast_indicate(in, -1);
00807       }
00808    }
00809 }
00810 
00811 /* argument used for some functions. */
00812 struct privacy_args {
00813    int sentringing;
00814    int privdb_val;
00815    char privcid[256];
00816    char privintro[1024];
00817    char status[256];
00818 };
00819 
00820 static struct ast_channel *wait_for_answer(struct ast_channel *in,
00821    struct chanlist *outgoing, int *to, struct ast_flags64 *peerflags,
00822    struct privacy_args *pa,
00823    const struct cause_args *num_in, int *result)
00824 {
00825    struct cause_args num = *num_in;
00826    int prestart = num.busy + num.congestion + num.nochan;
00827    int orig = *to;
00828    struct ast_channel *peer = NULL;
00829    /* single is set if only one destination is enabled */
00830    int single = outgoing && !outgoing->next && !ast_test_flag64(outgoing, OPT_MUSICBACK | OPT_RINGBACK);
00831 #ifdef HAVE_EPOLL
00832    struct chanlist *epollo;
00833 #endif
00834 
00835    if (single) {
00836       /* Turn off hold music, etc */
00837       ast_deactivate_generator(in);
00838       /* If we are calling a single channel, make them compatible for in-band tone purpose */
00839       ast_channel_make_compatible(outgoing->chan, in);
00840    }
00841 
00842 #ifdef HAVE_EPOLL
00843    for (epollo = outgoing; epollo; epollo = epollo->next)
00844       ast_poll_channel_add(in, epollo->chan);
00845 #endif
00846 
00847    while (*to && !peer) {
00848       struct chanlist *o;
00849       int pos = 0; /* how many channels do we handle */
00850       int numlines = prestart;
00851       struct ast_channel *winner;
00852       struct ast_channel *watchers[AST_MAX_WATCHERS];
00853 
00854       watchers[pos++] = in;
00855       for (o = outgoing; o; o = o->next) {
00856          /* Keep track of important channels */
00857          if (ast_test_flag64(o, DIAL_STILLGOING) && o->chan)
00858             watchers[pos++] = o->chan;
00859          numlines++;
00860       }
00861       if (pos == 1) { /* only the input channel is available */
00862          if (numlines == (num.busy + num.congestion + num.nochan)) {
00863             ast_verb(2, "Everyone is busy/congested at this time (%d:%d/%d/%d)\n", numlines, num.busy, num.congestion, num.nochan);
00864             if (num.busy)
00865                strcpy(pa->status, "BUSY");
00866             else if (num.congestion)
00867                strcpy(pa->status, "CONGESTION");
00868             else if (num.nochan)
00869                strcpy(pa->status, "CHANUNAVAIL");
00870          } else {
00871             ast_verb(3, "No one is available to answer at this time (%d:%d/%d/%d)\n", numlines, num.busy, num.congestion, num.nochan);
00872          }
00873          *to = 0;
00874          return NULL;
00875       }
00876       winner = ast_waitfor_n(watchers, pos, to);
00877       for (o = outgoing; o; o = o->next) {
00878          struct ast_frame *f;
00879          struct ast_channel *c = o->chan;
00880 
00881          if (c == NULL)
00882             continue;
00883          if (ast_test_flag64(o, DIAL_STILLGOING) && c->_state == AST_STATE_UP) {
00884             if (!peer) {
00885                ast_verb(3, "%s answered %s\n", c->name, in->name);
00886                peer = c;
00887                ast_copy_flags64(peerflags, o,
00888                   OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
00889                   OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
00890                   OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
00891                   OPT_CALLEE_PARK | OPT_CALLER_PARK |
00892                   OPT_CALLEE_MIXMONITOR | OPT_CALLER_MIXMONITOR |
00893                   DIAL_NOFORWARDHTML);
00894                ast_string_field_set(c, dialcontext, "");
00895                ast_copy_string(c->exten, "", sizeof(c->exten));
00896             }
00897             continue;
00898          }
00899          if (c != winner)
00900             continue;
00901          /* here, o->chan == c == winner */
00902          if (!ast_strlen_zero(c->call_forward)) {
00903             do_forward(o, &num, peerflags, single);
00904             continue;
00905          }
00906          f = ast_read(winner);
00907          if (!f) {
00908             in->hangupcause = c->hangupcause;
00909 #ifdef HAVE_EPOLL
00910             ast_poll_channel_del(in, c);
00911 #endif
00912             ast_hangup(c);
00913             c = o->chan = NULL;
00914             ast_clear_flag64(o, DIAL_STILLGOING);
00915             handle_cause(in->hangupcause, &num);
00916             continue;
00917          }
00918          if (f->frametype == AST_FRAME_CONTROL) {
00919             switch(f->subclass) {
00920             case AST_CONTROL_ANSWER:
00921                /* This is our guy if someone answered. */
00922                if (!peer) {
00923                   ast_verb(3, "%s answered %s\n", c->name, in->name);
00924                   peer = c;
00925                   if (peer->cdr) {
00926                      peer->cdr->answer = ast_tvnow();
00927                      peer->cdr->disposition = AST_CDR_ANSWERED;
00928                   }
00929                   ast_copy_flags64(peerflags, o,
00930                      OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
00931                      OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
00932                      OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
00933                      OPT_CALLEE_PARK | OPT_CALLER_PARK |
00934                      OPT_CALLEE_MIXMONITOR | OPT_CALLER_MIXMONITOR |
00935                      DIAL_NOFORWARDHTML);
00936                   ast_string_field_set(c, dialcontext, "");
00937                   ast_copy_string(c->exten, "", sizeof(c->exten));
00938                   if (CAN_EARLY_BRIDGE(peerflags, in, peer))
00939                      /* Setup early bridge if appropriate */
00940                      ast_channel_early_bridge(in, peer);
00941                }
00942                /* If call has been answered, then the eventual hangup is likely to be normal hangup */
00943                in->hangupcause = AST_CAUSE_NORMAL_CLEARING;
00944                c->hangupcause = AST_CAUSE_NORMAL_CLEARING;
00945                break;
00946             case AST_CONTROL_BUSY:
00947                ast_verb(3, "%s is busy\n", c->name);
00948                in->hangupcause = c->hangupcause;
00949                ast_hangup(c);
00950                c = o->chan = NULL;
00951                ast_clear_flag64(o, DIAL_STILLGOING);
00952                handle_cause(AST_CAUSE_BUSY, &num);
00953                break;
00954             case AST_CONTROL_CONGESTION:
00955                ast_verb(3, "%s is circuit-busy\n", c->name);
00956                in->hangupcause = c->hangupcause;
00957                ast_hangup(c);
00958                c = o->chan = NULL;
00959                ast_clear_flag64(o, DIAL_STILLGOING);
00960                handle_cause(AST_CAUSE_CONGESTION, &num);
00961                break;
00962             case AST_CONTROL_RINGING:
00963                ast_verb(3, "%s is ringing\n", c->name);
00964                /* Setup early media if appropriate */
00965                if (single && CAN_EARLY_BRIDGE(peerflags, in, c))
00966                   ast_channel_early_bridge(in, c);
00967                if (!(pa->sentringing) && !ast_test_flag64(outgoing, OPT_MUSICBACK)) {
00968                   ast_indicate(in, AST_CONTROL_RINGING);
00969                   pa->sentringing++;
00970                }
00971                break;
00972             case AST_CONTROL_PROGRESS:
00973                ast_verb(3, "%s is making progress passing it to %s\n", c->name, in->name);
00974                /* Setup early media if appropriate */
00975                if (single && CAN_EARLY_BRIDGE(peerflags, in, c))
00976                   ast_channel_early_bridge(in, c);
00977                if (!ast_test_flag64(outgoing, OPT_RINGBACK))
00978                   if (single || (!single && !pa->sentringing)) {
00979                      ast_indicate(in, AST_CONTROL_PROGRESS);
00980                   }
00981                break;
00982             case AST_CONTROL_VIDUPDATE:
00983                ast_verb(3, "%s requested a video update, passing it to %s\n", c->name, in->name);
00984                ast_indicate(in, AST_CONTROL_VIDUPDATE);
00985                break;
00986             case AST_CONTROL_SRCUPDATE:
00987                ast_verb(3, "%s requested a source update, passing it to %s\n", c->name, in->name);
00988                ast_indicate(in, AST_CONTROL_SRCUPDATE);
00989                break;
00990             case AST_CONTROL_PROCEEDING:
00991                ast_verb(3, "%s is proceeding passing it to %s\n", c->name, in->name);
00992                if (single && CAN_EARLY_BRIDGE(peerflags, in, c))
00993                   ast_channel_early_bridge(in, c);
00994                if (!ast_test_flag64(outgoing, OPT_RINGBACK))
00995                   ast_indicate(in, AST_CONTROL_PROCEEDING);
00996                break;
00997             case AST_CONTROL_HOLD:
00998                ast_verb(3, "Call on %s placed on hold\n", c->name);
00999                ast_indicate(in, AST_CONTROL_HOLD);
01000                break;
01001             case AST_CONTROL_UNHOLD:
01002                ast_verb(3, "Call on %s left from hold\n", c->name);
01003                ast_indicate(in, AST_CONTROL_UNHOLD);
01004                break;
01005             case AST_CONTROL_OFFHOOK:
01006             case AST_CONTROL_FLASH:
01007                /* Ignore going off hook and flash */
01008                break;
01009             case -1:
01010                if (!ast_test_flag64(outgoing, OPT_RINGBACK | OPT_MUSICBACK)) {
01011                   ast_verb(3, "%s stopped sounds\n", c->name);
01012                   ast_indicate(in, -1);
01013                   pa->sentringing = 0;
01014                }
01015                break;
01016             default:
01017                ast_debug(1, "Dunno what to do with control type %d\n", f->subclass);
01018             }
01019          } else if (single) {
01020             switch (f->frametype) {
01021                case AST_FRAME_VOICE:
01022                case AST_FRAME_IMAGE:
01023                case AST_FRAME_TEXT:
01024                   if (ast_write(in, f)) {
01025                      ast_log(LOG_WARNING, "Unable to write frame\n");
01026                   }
01027                   break;
01028                case AST_FRAME_HTML:
01029                   if (!ast_test_flag64(outgoing, DIAL_NOFORWARDHTML) && ast_channel_sendhtml(in, f->subclass, f->data.ptr, f->datalen) == -1) {
01030                      ast_log(LOG_WARNING, "Unable to send URL\n");
01031                   }
01032                   break;
01033                default:
01034                   break;
01035             }
01036          }
01037          ast_frfree(f);
01038       } /* end for */
01039       if (winner == in) {
01040          struct ast_frame *f = ast_read(in);
01041 #if 0
01042          if (f && (f->frametype != AST_FRAME_VOICE))
01043             printf("Frame type: %d, %d\n", f->frametype, f->subclass);
01044          else if (!f || (f->frametype != AST_FRAME_VOICE))
01045             printf("Hangup received on %s\n", in->name);
01046 #endif
01047          if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
01048             /* Got hung up */
01049             *to = -1;
01050             strcpy(pa->status, "CANCEL");
01051             ast_cdr_noanswer(in->cdr);
01052             if (f) {
01053                if (f->data.uint32) {
01054                   in->hangupcause = f->data.uint32;
01055                }
01056                ast_frfree(f);
01057             }
01058             return NULL;
01059          }
01060 
01061          /* now f is guaranteed non-NULL */
01062          if (f->frametype == AST_FRAME_DTMF) {
01063             if (ast_test_flag64(peerflags, OPT_DTMF_EXIT)) {
01064                const char *context;
01065                ast_channel_lock(in);
01066                context = pbx_builtin_getvar_helper(in, "EXITCONTEXT");
01067                if (onedigit_goto(in, context, (char) f->subclass, 1)) {
01068                   ast_verb(3, "User hit %c to disconnect call.\n", f->subclass);
01069                   *to = 0;
01070                   ast_cdr_noanswer(in->cdr);
01071                   *result = f->subclass;
01072                   strcpy(pa->status, "CANCEL");
01073                   ast_frfree(f);
01074                   ast_channel_unlock(in);
01075                   return NULL;
01076                }
01077                ast_channel_unlock(in);
01078             }
01079 
01080             if (ast_test_flag64(peerflags, OPT_CALLER_HANGUP) &&
01081                   (f->subclass == '*')) { /* hmm it it not guaranteed to be '*' anymore. */
01082                ast_verb(3, "User hit %c to disconnect call.\n", f->subclass);
01083                *to = 0;
01084                strcpy(pa->status, "CANCEL");
01085                ast_cdr_noanswer(in->cdr);
01086                ast_frfree(f);
01087                return NULL;
01088             }
01089          }
01090 
01091          /* Forward HTML stuff */
01092          if (single && (f->frametype == AST_FRAME_HTML) && !ast_test_flag64(outgoing, DIAL_NOFORWARDHTML))
01093             if (ast_channel_sendhtml(outgoing->chan, f->subclass, f->data.ptr, f->datalen) == -1)
01094                ast_log(LOG_WARNING, "Unable to send URL\n");
01095 
01096          if (single && ((f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_DTMF_BEGIN) || (f->frametype == AST_FRAME_DTMF_END)))  {
01097             if (ast_write(outgoing->chan, f))
01098                ast_log(LOG_WARNING, "Unable to forward voice or dtmf\n");
01099          }
01100          if (single && (f->frametype == AST_FRAME_CONTROL) &&
01101             ((f->subclass == AST_CONTROL_HOLD) ||
01102             (f->subclass == AST_CONTROL_UNHOLD) ||
01103             (f->subclass == AST_CONTROL_VIDUPDATE) ||
01104              (f->subclass == AST_CONTROL_SRCUPDATE))) {
01105             ast_verb(3, "%s requested special control %d, passing it to %s\n", in->name, f->subclass, outgoing->chan->name);
01106             ast_indicate_data(outgoing->chan, f->subclass, f->data.ptr, f->datalen);
01107          }
01108          ast_frfree(f);
01109       }
01110       if (!*to)
01111          ast_verb(3, "Nobody picked up in %d ms\n", orig);
01112       if (!*to || ast_check_hangup(in))
01113          ast_cdr_noanswer(in->cdr);
01114    }
01115 
01116 #ifdef HAVE_EPOLL
01117    for (epollo = outgoing; epollo; epollo = epollo->next) {
01118       if (epollo->chan)
01119          ast_poll_channel_del(in, epollo->chan);
01120    }
01121 #endif
01122 
01123    return peer;
01124 }
01125 
01126 static void replace_macro_delimiter(char *s)
01127 {
01128    for (; *s; s++)
01129       if (*s == '^')
01130          *s = ',';
01131 }
01132 
01133 /* returns true if there is a valid privacy reply */
01134 static int valid_priv_reply(struct ast_flags64 *opts, int res)
01135 {
01136    if (res < '1')
01137       return 0;
01138    if (ast_test_flag64(opts, OPT_PRIVACY) && res <= '5')
01139       return 1;
01140    if (ast_test_flag64(opts, OPT_SCREENING) && res <= '4')
01141       return 1;
01142    return 0;
01143 }
01144 
01145 static int do_timelimit(struct ast_channel *chan, struct ast_bridge_config *config,
01146    char *parse, struct timeval *calldurationlimit)
01147 {
01148    char *stringp = ast_strdupa(parse);
01149    char *limit_str, *warning_str, *warnfreq_str;
01150    const char *var;
01151    int play_to_caller = 0, play_to_callee = 0;
01152    int delta;
01153 
01154    limit_str = strsep(&stringp, ":");
01155    warning_str = strsep(&stringp, ":");
01156    warnfreq_str = strsep(&stringp, ":");
01157 
01158    config->timelimit = atol(limit_str);
01159    if (warning_str)
01160       config->play_warning = atol(warning_str);
01161    if (warnfreq_str)
01162       config->warning_freq = atol(warnfreq_str);
01163 
01164    if (!config->timelimit) {
01165       ast_log(LOG_WARNING, "Dial does not accept L(%s), hanging up.\n", limit_str);
01166       config->timelimit = config->play_warning = config->warning_freq = 0;
01167       config->warning_sound = NULL;
01168       return -1; /* error */
01169    } else if ( (delta = config->play_warning - config->timelimit) > 0) {
01170       int w = config->warning_freq;
01171 
01172       /* If the first warning is requested _after_ the entire call would end,
01173          and no warning frequency is requested, then turn off the warning. If
01174          a warning frequency is requested, reduce the 'first warning' time by
01175          that frequency until it falls within the call's total time limit.
01176          Graphically:
01177               timelim->|    delta        |<-playwarning
01178          0__________________|_________________|
01179                 | w  |    |    |    |
01180 
01181          so the number of intervals to cut is 1+(delta-1)/w
01182       */
01183 
01184       if (w == 0) {
01185          config->play_warning = 0;
01186       } else {
01187          config->play_warning -= w * ( 1 + (delta-1)/w );
01188          if (config->play_warning < 1)
01189             config->play_warning = config->warning_freq = 0;
01190       }
01191    }
01192    
01193    ast_channel_lock(chan);
01194 
01195    var = pbx_builtin_getvar_helper(chan, "LIMIT_PLAYAUDIO_CALLER");
01196 
01197    play_to_caller = var ? ast_true(var) : 1;
01198 
01199    var = pbx_builtin_getvar_helper(chan, "LIMIT_PLAYAUDIO_CALLEE");
01200    play_to_callee = var ? ast_true(var) : 0;
01201 
01202    if (!play_to_caller && !play_to_callee)
01203       play_to_caller = 1;
01204 
01205    var = pbx_builtin_getvar_helper(chan, "LIMIT_WARNING_FILE");
01206    config->warning_sound = !ast_strlen_zero(var) ? ast_strdup(var) : ast_strdup("timeleft");
01207 
01208    /* The code looking at config wants a NULL, not just "", to decide
01209     * that the message should not be played, so we replace "" with NULL.
01210     * Note, pbx_builtin_getvar_helper _can_ return NULL if the variable is
01211     * not found.
01212     */
01213 
01214    var = pbx_builtin_getvar_helper(chan, "LIMIT_TIMEOUT_FILE");
01215    config->end_sound = !ast_strlen_zero(var) ? ast_strdup(var) : NULL;
01216 
01217    var = pbx_builtin_getvar_helper(chan, "LIMIT_CONNECT_FILE");
01218    config->start_sound = !ast_strlen_zero(var) ? ast_strdup(var) : NULL;
01219 
01220    ast_channel_unlock(chan);
01221 
01222    /* undo effect of S(x) in case they are both used */
01223    calldurationlimit->tv_sec = 0;
01224    calldurationlimit->tv_usec = 0;
01225 
01226    /* more efficient to do it like S(x) does since no advanced opts */
01227    if (!config->play_warning && !config->start_sound && !config->end_sound && config->timelimit) {
01228       calldurationlimit->tv_sec = config->timelimit / 1000;
01229       calldurationlimit->tv_usec = (config->timelimit % 1000) * 1000;
01230       ast_verb(3, "Setting call duration limit to %.3lf seconds.\n",
01231          calldurationlimit->tv_sec + calldurationlimit->tv_usec / 1000000.0);
01232       config->timelimit = play_to_caller = play_to_callee =
01233       config->play_warning = config->warning_freq = 0;
01234    } else {
01235       ast_verb(3, "Limit Data for this call:\n");
01236       ast_verb(4, "timelimit      = %ld\n", config->timelimit);
01237       ast_verb(4, "play_warning   = %ld\n", config->play_warning);
01238       ast_verb(4, "play_to_caller = %s\n", play_to_caller ? "yes" : "no");
01239       ast_verb(4, "play_to_callee = %s\n", play_to_callee ? "yes" : "no");
01240       ast_verb(4, "warning_freq   = %ld\n", config->warning_freq);
01241       ast_verb(4, "start_sound    = %s\n", S_OR(config->start_sound, ""));
01242       ast_verb(4, "warning_sound  = %s\n", config->warning_sound);
01243       ast_verb(4, "end_sound      = %s\n", S_OR(config->end_sound, ""));
01244    }
01245    if (play_to_caller)
01246       ast_set_flag(&(config->features_caller), AST_FEATURE_PLAY_WARNING);
01247    if (play_to_callee)
01248       ast_set_flag(&(config->features_callee), AST_FEATURE_PLAY_WARNING);
01249    return 0;
01250 }
01251 
01252 static int do_privacy(struct ast_channel *chan, struct ast_channel *peer,
01253    struct ast_flags64 *opts, char **opt_args, struct privacy_args *pa)
01254 {
01255 
01256    int res2;
01257    int loopcount = 0;
01258 
01259    /* Get the user's intro, store it in priv-callerintros/$CID,
01260       unless it is already there-- this should be done before the
01261       call is actually dialed  */
01262 
01263    /* all ring indications and moh for the caller has been halted as soon as the
01264       target extension was picked up. We are going to have to kill some
01265       time and make the caller believe the peer hasn't picked up yet */
01266 
01267    if (ast_test_flag64(opts, OPT_MUSICBACK) && !ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
01268       char *original_moh = ast_strdupa(chan->musicclass);
01269       ast_indicate(chan, -1);
01270       ast_string_field_set(chan, musicclass, opt_args[OPT_ARG_MUSICBACK]);
01271       ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
01272       ast_string_field_set(chan, musicclass, original_moh);
01273    } else if (ast_test_flag64(opts, OPT_RINGBACK)) {
01274       ast_indicate(chan, AST_CONTROL_RINGING);
01275       pa->sentringing++;
01276    }
01277 
01278    /* Start autoservice on the other chan ?? */
01279    res2 = ast_autoservice_start(chan);
01280    /* Now Stream the File */
01281    for (loopcount = 0; loopcount < 3; loopcount++) {
01282       if (res2 && loopcount == 0) /* error in ast_autoservice_start() */
01283          break;
01284       if (!res2) /* on timeout, play the message again */
01285          res2 = ast_play_and_wait(peer, "priv-callpending");
01286       if (!valid_priv_reply(opts, res2))
01287          res2 = 0;
01288       /* priv-callpending script:
01289          "I have a caller waiting, who introduces themselves as:"
01290       */
01291       if (!res2)
01292          res2 = ast_play_and_wait(peer, pa->privintro);
01293       if (!valid_priv_reply(opts, res2))
01294          res2 = 0;
01295       /* now get input from the called party, as to their choice */
01296       if (!res2) {
01297          /* XXX can we have both, or they are mutually exclusive ? */
01298          if (ast_test_flag64(opts, OPT_PRIVACY))
01299             res2 = ast_play_and_wait(peer, "priv-callee-options");
01300          if (ast_test_flag64(opts, OPT_SCREENING))
01301             res2 = ast_play_and_wait(peer, "screen-callee-options");
01302       }
01303       /*! \page DialPrivacy Dial Privacy scripts
01304       \par priv-callee-options script:
01305          "Dial 1 if you wish this caller to reach you directly in the future,
01306             and immediately connect to their incoming call
01307           Dial 2 if you wish to send this caller to voicemail now and
01308             forevermore.
01309           Dial 3 to send this caller to the torture menus, now and forevermore.
01310           Dial 4 to send this caller to a simple "go away" menu, now and forevermore.
01311           Dial 5 to allow this caller to come straight thru to you in the future,
01312             but right now, just this once, send them to voicemail."
01313       \par screen-callee-options script:
01314          "Dial 1 if you wish to immediately connect to the incoming call
01315           Dial 2 if you wish to send this caller to voicemail.
01316           Dial 3 to send this caller to the torture menus.
01317           Dial 4 to send this caller to a simple "go away" menu.
01318       */
01319       if (valid_priv_reply(opts, res2))
01320          break;
01321       /* invalid option */
01322       res2 = ast_play_and_wait(peer, "vm-sorry");
01323    }
01324 
01325    if (ast_test_flag64(opts, OPT_MUSICBACK)) {
01326       ast_moh_stop(chan);
01327    } else if (ast_test_flag64(opts, OPT_RINGBACK)) {
01328       ast_indicate(chan, -1);
01329       pa->sentringing = 0;
01330    }
01331    ast_autoservice_stop(chan);
01332    if (ast_test_flag64(opts, OPT_PRIVACY) && (res2 >= '1' && res2 <= '5')) {
01333       /* map keypresses to various things, the index is res2 - '1' */
01334       static const char *_val[] = { "ALLOW", "DENY", "TORTURE", "KILL", "ALLOW" };
01335       static const int _flag[] = { AST_PRIVACY_ALLOW, AST_PRIVACY_DENY, AST_PRIVACY_TORTURE, AST_PRIVACY_KILL, AST_PRIVACY_ALLOW};
01336       int i = res2 - '1';
01337       ast_verb(3, "--Set privacy database entry %s/%s to %s\n",
01338          opt_args[OPT_ARG_PRIVACY], pa->privcid, _val[i]);
01339       ast_privacy_set(opt_args[OPT_ARG_PRIVACY], pa->privcid, _flag[i]);
01340    }
01341    switch (res2) {
01342    case '1':
01343       break;
01344    case '2':
01345       ast_copy_string(pa->status, "NOANSWER", sizeof(pa->status));
01346       break;
01347    case '3':
01348       ast_copy_string(pa->status, "TORTURE", sizeof(pa->status));
01349       break;
01350    case '4':
01351       ast_copy_string(pa->status, "DONTCALL", sizeof(pa->status));
01352       break;
01353    case '5':
01354       /* XXX should we set status to DENY ? */
01355       if (ast_test_flag64(opts, OPT_PRIVACY))
01356          break;
01357       /* if not privacy, then 5 is the same as "default" case */
01358    default: /* bad input or -1 if failure to start autoservice */
01359       /* well, if the user messes up, ... he had his chance... What Is The Best Thing To Do?  */
01360       /* well, there seems basically two choices. Just patch the caller thru immediately,
01361            or,... put 'em thru to voicemail. */
01362       /* since the callee may have hung up, let's do the voicemail thing, no database decision */
01363       ast_log(LOG_NOTICE, "privacy: no valid response from the callee. Sending the caller to voicemail, the callee isn't responding\n");
01364       /* XXX should we set status to DENY ? */
01365       /* XXX what about the privacy flags ? */
01366       break;
01367    }
01368 
01369    if (res2 == '1') { /* the only case where we actually connect */
01370       /* if the intro is NOCALLERID, then there's no reason to leave it on disk, it'll
01371          just clog things up, and it's not useful information, not being tied to a CID */
01372       if (strncmp(pa->privcid, "NOCALLERID", 10) == 0 || ast_test_flag64(opts, OPT_SCREEN_NOINTRO)) {
01373          ast_filedelete(pa->privintro, NULL);
01374          if (ast_fileexists(pa->privintro, NULL, NULL) > 0)
01375             ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", pa->privintro);
01376          else
01377             ast_verb(3, "Successfully deleted %s intro file\n", pa->privintro);
01378       }
01379       return 0; /* the good exit path */
01380    } else {
01381       ast_hangup(peer); /* hang up on the callee -- he didn't want to talk anyway! */
01382       return -1;
01383    }
01384 }
01385 
01386 /*! \brief returns 1 if successful, 0 or <0 if the caller should 'goto out' */
01387 static int setup_privacy_args(struct privacy_args *pa,
01388    struct ast_flags64 *opts, char *opt_args[], struct ast_channel *chan)
01389 {
01390    char callerid[60];
01391    int res;
01392    char *l;
01393    int silencethreshold;
01394 
01395    if (!ast_strlen_zero(chan->cid.cid_num)) {
01396       l = ast_strdupa(chan->cid.cid_num);
01397       ast_shrink_phone_number(l);
01398       if (ast_test_flag64(opts, OPT_PRIVACY) ) {
01399          ast_verb(3, "Privacy DB is '%s', clid is '%s'\n", opt_args[OPT_ARG_PRIVACY], l);
01400          pa->privdb_val = ast_privacy_check(opt_args[OPT_ARG_PRIVACY], l);
01401       } else {
01402          ast_verb(3, "Privacy Screening, clid is '%s'\n", l);
01403          pa->privdb_val = AST_PRIVACY_UNKNOWN;
01404       }
01405    } else {
01406       char *tnam, *tn2;
01407 
01408       tnam = ast_strdupa(chan->name);
01409       /* clean the channel name so slashes don't try to end up in disk file name */
01410       for (tn2 = tnam; *tn2; tn2++) {
01411          if (*tn2 == '/')  /* any other chars to be afraid of? */
01412             *tn2 = '=';
01413       }
01414       ast_verb(3, "Privacy-- callerid is empty\n");
01415 
01416       snprintf(callerid, sizeof(callerid), "NOCALLERID_%s%s", chan->exten, tnam);
01417       l = callerid;
01418       pa->privdb_val = AST_PRIVACY_UNKNOWN;
01419    }
01420 
01421    ast_copy_string(pa->privcid, l, sizeof(pa->privcid));
01422 
01423    if (strncmp(pa->privcid, "NOCALLERID", 10) != 0 && ast_test_flag64(opts, OPT_SCREEN_NOCLID)) {
01424       /* if callerid is set and OPT_SCREEN_NOCLID is set also */
01425       ast_verb(3, "CallerID set (%s); N option set; Screening should be off\n", pa->privcid);
01426       pa->privdb_val = AST_PRIVACY_ALLOW;
01427    } else if (ast_test_flag64(opts, OPT_SCREEN_NOCLID) && strncmp(pa->privcid, "NOCALLERID", 10) == 0) {
01428       ast_verb(3, "CallerID blank; N option set; Screening should happen; dbval is %d\n", pa->privdb_val);
01429    }
01430    
01431    if (pa->privdb_val == AST_PRIVACY_DENY) {
01432       ast_verb(3, "Privacy DB reports PRIVACY_DENY for this callerid. Dial reports unavailable\n");
01433       ast_copy_string(pa->status, "NOANSWER", sizeof(pa->status));
01434       return 0;
01435    } else if (pa->privdb_val == AST_PRIVACY_KILL) {
01436       ast_copy_string(pa->status, "DONTCALL", sizeof(pa->status));
01437       return 0; /* Is this right? */
01438    } else if (pa->privdb_val == AST_PRIVACY_TORTURE) {
01439       ast_copy_string(pa->status, "TORTURE", sizeof(pa->status));
01440       return 0; /* is this right??? */
01441    } else if (pa->privdb_val == AST_PRIVACY_UNKNOWN) {
01442       /* Get the user's intro, store it in priv-callerintros/$CID,
01443          unless it is already there-- this should be done before the
01444          call is actually dialed  */
01445 
01446       /* make sure the priv-callerintros dir actually exists */
01447       snprintf(pa->privintro, sizeof(pa->privintro), "%s/sounds/priv-callerintros", ast_config_AST_DATA_DIR);
01448       if ((res = ast_mkdir(pa->privintro, 0755))) {
01449          ast_log(LOG_WARNING, "privacy: can't create directory priv-callerintros: %s\n", strerror(res));
01450          return -1;
01451       }
01452 
01453       snprintf(pa->privintro, sizeof(pa->privintro), "priv-callerintros/%s", pa->privcid);
01454       if (ast_fileexists(pa->privintro, NULL, NULL ) > 0 && strncmp(pa->privcid, "NOCALLERID", 10) != 0) {
01455          /* the DELUX version of this code would allow this caller the
01456             option to hear and retape their previously recorded intro.
01457          */
01458       } else {
01459          int duration; /* for feedback from play_and_wait */
01460          /* the file doesn't exist yet. Let the caller submit his
01461             vocal intro for posterity */
01462          /* priv-recordintro script:
01463 
01464             "At the tone, please say your name:"
01465 
01466          */
01467          silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE);
01468          ast_answer(chan);
01469          res = ast_play_and_record(chan, "priv-recordintro", pa->privintro, 4, "gsm", &duration, silencethreshold, 2000, 0);  /* NOTE: I've reduced the total time to 4 sec */
01470                            /* don't think we'll need a lock removed, we took care of
01471                               conflicts by naming the pa.privintro file */
01472          if (res == -1) {
01473             /* Delete the file regardless since they hung up during recording */
01474             ast_filedelete(pa->privintro, NULL);
01475             if (ast_fileexists(pa->privintro, NULL, NULL) > 0)
01476                ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", pa->privintro);
01477             else
01478                ast_verb(3, "Successfully deleted %s intro file\n", pa->privintro);
01479             return -1;
01480          }
01481          if (!ast_streamfile(chan, "vm-dialout", chan->language) )
01482             ast_waitstream(chan, "");
01483       }
01484    }
01485    return 1; /* success */
01486 }
01487 
01488 static void end_bridge_callback(void *data)
01489 {
01490    char buf[80];
01491    time_t end;
01492    struct ast_channel *chan = data;
01493 
01494    if (!chan->cdr) {
01495       return;
01496    }
01497 
01498    time(&end);
01499 
01500    ast_channel_lock(chan);
01501    if (chan->cdr->answer.tv_sec) {
01502       snprintf(buf, sizeof(buf), "%ld", (long) end - chan->cdr->answer.tv_sec);
01503       pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", buf);
01504    }
01505 
01506    if (chan->cdr->start.tv_sec) {
01507       snprintf(buf, sizeof(buf), "%ld", (long) end - chan->cdr->start.tv_sec);
01508       pbx_builtin_setvar_helper(chan, "DIALEDTIME", buf);
01509    }
01510    ast_channel_unlock(chan);
01511 }
01512 
01513 static void end_bridge_callback_data_fixup(struct ast_bridge_config *bconfig, struct ast_channel *originator, struct ast_channel *terminator) {
01514    bconfig->end_bridge_callback_data = originator;
01515 }
01516 
01517 static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags64 *peerflags, int *continue_exec)
01518 {
01519    int res = -1; /* default: error */
01520    char *rest, *cur; /* scan the list of destinations */
01521    struct chanlist *outgoing = NULL; /* list of destinations */
01522    struct ast_channel *peer;
01523    int to; /* timeout */
01524    struct cause_args num = { chan, 0, 0, 0 };
01525    int cause;
01526    char numsubst[256];
01527    char cidname[AST_MAX_EXTENSION] = "";
01528 
01529    struct ast_bridge_config config = { { 0, } };
01530    struct timeval calldurationlimit = { 0, };
01531    char *dtmfcalled = NULL, *dtmfcalling = NULL;
01532    struct privacy_args pa = {
01533       .sentringing = 0,
01534       .privdb_val = 0,
01535       .status = "INVALIDARGS",
01536    };
01537    int sentringing = 0, moh = 0;
01538    const char *outbound_group = NULL;
01539    int result = 0;
01540    char *parse;
01541    int opermode = 0;
01542    int delprivintro = 0;
01543    AST_DECLARE_APP_ARGS(args,
01544       AST_APP_ARG(peers);
01545       AST_APP_ARG(timeout);
01546       AST_APP_ARG(options);
01547       AST_APP_ARG(url);
01548    );
01549    struct ast_flags64 opts = { 0, };
01550    char *opt_args[OPT_ARG_ARRAY_SIZE];
01551    struct ast_datastore *datastore = NULL;
01552    int fulldial = 0, num_dialed = 0;
01553 
01554    /* Reset all DIAL variables back to blank, to prevent confusion (in case we don't reset all of them). */
01555    pbx_builtin_setvar_helper(chan, "DIALSTATUS", "");
01556    pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", "");
01557    pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", "");
01558    pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", "");
01559    pbx_builtin_setvar_helper(chan, "DIALEDTIME", "");
01560 
01561    if (ast_strlen_zero(data)) {
01562       ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
01563       pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
01564       return -1;
01565    }
01566 
01567    parse = ast_strdupa(data);
01568 
01569    AST_STANDARD_APP_ARGS(args, parse);
01570 
01571    if (!ast_strlen_zero(args.options) &&
01572       ast_app_parse_options64(dial_exec_options, &opts, opt_args, args.options)) {
01573       pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
01574       goto done;
01575    }
01576 
01577    if (ast_strlen_zero(args.peers)) {
01578       ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
01579       pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
01580       goto done;
01581    }
01582 
01583 
01584    if (ast_test_flag64(&opts, OPT_SCREEN_NOINTRO) && !ast_strlen_zero(opt_args[OPT_ARG_SCREEN_NOINTRO])) {
01585       delprivintro = atoi(opt_args[OPT_ARG_SCREEN_NOINTRO]);
01586 
01587       if (delprivintro < 0 || delprivintro > 1) {
01588          ast_log(LOG_WARNING, "Unknown argument %d specified to n option, ignoring\n", delprivintro);
01589          delprivintro = 0;
01590       }
01591    }
01592 
01593    if (ast_test_flag64(&opts, OPT_OPERMODE)) {
01594       opermode = ast_strlen_zero(opt_args[OPT_ARG_OPERMODE]) ? 1 : atoi(opt_args[OPT_ARG_OPERMODE]);
01595       ast_verb(3, "Setting operator services mode to %d.\n", opermode);
01596    }
01597    
01598    if (ast_test_flag64(&opts, OPT_DURATION_STOP) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_STOP])) {
01599       calldurationlimit.tv_sec = atoi(opt_args[OPT_ARG_DURATION_STOP]);
01600       if (!calldurationlimit.tv_sec) {
01601          ast_log(LOG_WARNING, "Dial does not accept S(%s), hanging up.\n", opt_args[OPT_ARG_DURATION_STOP]);
01602          pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
01603          goto done;
01604       }
01605       ast_verb(3, "Setting call duration limit to %.3lf seconds.\n", calldurationlimit.tv_sec + calldurationlimit.tv_usec / 1000000.0);
01606    }
01607 
01608    if (ast_test_flag64(&opts, OPT_SENDDTMF) && !ast_strlen_zero(opt_args[OPT_ARG_SENDDTMF])) {
01609       dtmfcalling = opt_args[OPT_ARG_SENDDTMF];
01610       dtmfcalled = strsep(&dtmfcalling, ":");
01611    }
01612 
01613    if (ast_test_flag64(&opts, OPT_DURATION_LIMIT) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_LIMIT])) {
01614       if (do_timelimit(chan, &config, opt_args[OPT_ARG_DURATION_LIMIT], &calldurationlimit))
01615          goto done;
01616    }
01617 
01618    if (ast_test_flag64(&opts, OPT_RESETCDR) && chan->cdr)
01619       ast_cdr_reset(chan->cdr, NULL);
01620    if (ast_test_flag64(&opts, OPT_PRIVACY) && ast_strlen_zero(opt_args[OPT_ARG_PRIVACY]))
01621       opt_args[OPT_ARG_PRIVACY] = ast_strdupa(chan->exten);
01622 
01623    if (ast_test_flag64(&opts, OPT_PRIVACY) || ast_test_flag64(&opts, OPT_SCREENING)) {
01624       res = setup_privacy_args(&pa, &opts, opt_args, chan);
01625       if (res <= 0)
01626          goto out;
01627       res = -1; /* reset default */
01628    }
01629 
01630    if (ast_test_flag64(&opts, OPT_DTMF_EXIT)) {
01631       __ast_answer(chan, 0, 0);
01632    }
01633 
01634    if (continue_exec)
01635       *continue_exec = 0;
01636 
01637    /* If a channel group has been specified, get it for use when we create peer channels */
01638 
01639    ast_channel_lock(chan);
01640    if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP_ONCE"))) {
01641       outbound_group = ast_strdupa(outbound_group);   
01642       pbx_builtin_setvar_helper(chan, "OUTBOUND_GROUP_ONCE", NULL);
01643    } else if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP"))) {
01644       outbound_group = ast_strdupa(outbound_group);
01645    }
01646    ast_channel_unlock(chan);  
01647    ast_copy_flags64(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID | OPT_CALLER_HANGUP | OPT_IGNORE_FORWARDING | OPT_ANNOUNCE | OPT_CALLEE_MACRO | OPT_CALLEE_GOSUB);
01648 
01649    /* loop through the list of dial destinations */
01650    rest = args.peers;
01651    while ((cur = strsep(&rest, "&")) ) {
01652       struct chanlist *tmp;
01653       struct ast_channel *tc; /* channel for this destination */
01654       /* Get a technology/[device:]number pair */
01655       char *number = cur;
01656       char *interface = ast_strdupa(number);
01657       char *tech = strsep(&number, "/");
01658       /* find if we already dialed this interface */
01659       struct ast_dialed_interface *di;
01660       AST_LIST_HEAD(, ast_dialed_interface) *dialed_interfaces;
01661       num_dialed++;
01662       if (!number) {
01663          ast_log(LOG_WARNING, "Dial argument takes format (technology/[device:]number1)\n");
01664          goto out;
01665       }
01666       if (!(tmp = ast_calloc(1, sizeof(*tmp))))
01667          goto out;
01668       if (opts.flags) {
01669          ast_copy_flags64(tmp, &opts,
01670             OPT_CANCEL_ELSEWHERE |
01671             OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
01672             OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
01673             OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
01674             OPT_CALLEE_PARK | OPT_CALLER_PARK |
01675             OPT_CALLEE_MIXMONITOR | OPT_CALLER_MIXMONITOR |
01676             OPT_RINGBACK | OPT_MUSICBACK | OPT_FORCECLID);
01677          ast_set2_flag64(tmp, args.url, DIAL_NOFORWARDHTML);
01678       }
01679       ast_copy_string(numsubst, number, sizeof(numsubst));
01680       /* Request the peer */
01681 
01682       ast_channel_lock(chan);
01683       datastore = ast_channel_datastore_find(chan, &dialed_interface_info, NULL);
01684       ast_channel_unlock(chan);
01685 
01686       if (datastore)
01687          dialed_interfaces = datastore->data;
01688       else {
01689          if (!(datastore = ast_datastore_alloc(&dialed_interface_info, NULL))) {
01690             ast_log(LOG_WARNING, "Unable to create channel datastore for dialed interfaces. Aborting!\n");
01691             ast_free(tmp);
01692             goto out;
01693          }
01694 
01695          datastore->inheritance = DATASTORE_INHERIT_FOREVER;
01696 
01697          if (!(dialed_interfaces = ast_calloc(1, sizeof(*dialed_interfaces)))) {
01698             ast_datastore_free(datastore);
01699             ast_free(tmp);
01700             goto out;
01701          }
01702 
01703          datastore->data = dialed_interfaces;
01704          AST_LIST_HEAD_INIT(dialed_interfaces);
01705 
01706          ast_channel_lock(chan);
01707          ast_channel_datastore_add(chan, datastore);
01708          ast_channel_unlock(chan);
01709       }
01710 
01711       AST_LIST_LOCK(dialed_interfaces);
01712       AST_LIST_TRAVERSE(dialed_interfaces, di, list) {
01713          if (!strcasecmp(di->interface, interface)) {
01714             ast_log(LOG_WARNING, "Skipping dialing interface '%s' again since it has already been dialed\n",
01715                di->interface);
01716             break;
01717          }
01718       }
01719       AST_LIST_UNLOCK(dialed_interfaces);
01720 
01721       if (di) {
01722          fulldial++;
01723          ast_free(tmp);
01724          continue;
01725       }
01726 
01727       /* It is always ok to dial a Local interface.  We only keep track of
01728        * which "real" interfaces have been dialed.  The Local channel will
01729        * inherit this list so that if it ends up dialing a real interface,
01730        * it won't call one that has already been called. */
01731       if (strcasecmp(tech, "Local")) {
01732          if (!(di = ast_calloc(1, sizeof(*di) + strlen(interface)))) {
01733             AST_LIST_UNLOCK(dialed_interfaces);
01734             ast_free(tmp);
01735             goto out;
01736          }
01737          strcpy(di->interface, interface);
01738 
01739          AST_LIST_LOCK(dialed_interfaces);
01740          AST_LIST_INSERT_TAIL(dialed_interfaces, di, list);
01741          AST_LIST_UNLOCK(dialed_interfaces);
01742       }
01743 
01744       tc = ast_request(tech, chan->nativeformats, numsubst, &cause);
01745       if (!tc) {
01746          /* If we can't, just go on to the next call */
01747          ast_log(LOG_WARNING, "Unable to create channel of type '%s' (cause %d - %s)\n",
01748             tech, cause, ast_cause2str(cause));
01749          handle_cause(cause, &num);
01750          if (!rest) /* we are on the last destination */
01751             chan->hangupcause = cause;
01752          ast_free(tmp);
01753          continue;
01754       }
01755       pbx_builtin_setvar_helper(tc, "DIALEDPEERNUMBER", numsubst);
01756 
01757       /* Setup outgoing SDP to match incoming one */
01758       if (CAN_EARLY_BRIDGE(peerflags, chan, tc)) {
01759          ast_rtp_make_compatible(tc, chan, !outgoing && !rest);
01760       }
01761       
01762       /* Inherit specially named variables from parent channel */
01763       ast_channel_inherit_variables(chan, tc);
01764       ast_channel_datastore_inherit(chan, tc);
01765 
01766       tc->appl = "AppDial";
01767       tc->data = "(Outgoing Line)";
01768       memset(&tc->whentohangup, 0, sizeof(tc->whentohangup));
01769 
01770       S_REPLACE(tc->cid.cid_num, ast_strdup(chan->cid.cid_num));
01771       S_REPLACE(tc->cid.cid_name, ast_strdup(chan->cid.cid_name));
01772       S_REPLACE(tc->cid.cid_ani, ast_strdup(chan->cid.cid_ani));
01773       S_REPLACE(tc->cid.cid_rdnis, ast_strdup(chan->cid.cid_rdnis));
01774       
01775       ast_string_field_set(tc, accountcode, chan->accountcode);
01776       tc->cdrflags = chan->cdrflags;
01777       if (ast_strlen_zero(tc->musicclass))
01778          ast_string_field_set(tc, musicclass, chan->musicclass);
01779       /* Pass callingpres, type of number, tns, ADSI CPE, transfer capability */
01780       tc->cid.cid_pres = chan->cid.cid_pres;
01781       tc->cid.cid_ton = chan->cid.cid_ton;
01782       tc->cid.cid_tns = chan->cid.cid_tns;
01783       tc->cid.cid_ani2 = chan->cid.cid_ani2;
01784       tc->adsicpe = chan->adsicpe;
01785       tc->transfercapability = chan->transfercapability;
01786 
01787       /* If we have an outbound group, set this peer channel to it */
01788       if (outbound_group)
01789          ast_app_group_set_channel(tc, outbound_group);
01790       /* If the calling channel has the ANSWERED_ELSEWHERE flag set, inherit it. This is to support local channels */
01791       if (ast_test_flag(chan, AST_FLAG_ANSWERED_ELSEWHERE))
01792          ast_set_flag(tc, AST_FLAG_ANSWERED_ELSEWHERE);
01793 
01794       /* Check if we're forced by configuration */
01795       if (ast_test_flag64(&opts, OPT_CANCEL_ELSEWHERE))
01796           ast_set_flag(tc, AST_FLAG_ANSWERED_ELSEWHERE);
01797 
01798 
01799       /* Inherit context and extension */
01800       ast_string_field_set(tc, dialcontext, ast_strlen_zero(chan->macrocontext) ? chan->context : chan->macrocontext);
01801       if (!ast_strlen_zero(chan->macroexten))
01802          ast_copy_string(tc->exten, chan->macroexten, sizeof(tc->exten));
01803       else
01804          ast_copy_string(tc->exten, chan->exten, sizeof(tc->exten));
01805 
01806       res = ast_call(tc, numsubst, 0); /* Place the call, but don't wait on the answer */
01807 
01808       /* Save the info in cdr's that we called them */
01809       if (chan->cdr)
01810          ast_cdr_setdestchan(chan->cdr, tc->name);
01811 
01812       /* check the results of ast_call */
01813       if (res) {
01814          /* Again, keep going even if there's an error */
01815          ast_debug(1, "ast call on peer returned %d\n", res);
01816          ast_verb(3, "Couldn't call %s\n", numsubst);
01817          if (tc->hangupcause) {
01818             chan->hangupcause = tc->hangupcause;
01819          }
01820          ast_hangup(tc);
01821          tc = NULL;
01822          ast_free(tmp);
01823          continue;
01824       } else {
01825          senddialevent(chan, tc, numsubst);
01826          ast_verb(3, "Called %s\n", numsubst);
01827          if (!ast_test_flag64(peerflags, OPT_ORIGINAL_CLID))
01828             ast_set_callerid(tc, S_OR(chan->macroexten, chan->exten), get_cid_name(cidname, sizeof(cidname), chan), NULL);
01829       }
01830       /* Put them in the list of outgoing thingies...  We're ready now.
01831          XXX If we're forcibly removed, these outgoing calls won't get
01832          hung up XXX */
01833       ast_set_flag64(tmp, DIAL_STILLGOING);
01834       tmp->chan = tc;
01835       tmp->next = outgoing;
01836       outgoing = tmp;
01837       /* If this line is up, don't try anybody else */
01838       if (outgoing->chan->_state == AST_STATE_UP)
01839          break;
01840    }
01841    
01842    if (ast_strlen_zero(args.timeout)) {
01843       to = -1;
01844    } else {
01845       to = atoi(args.timeout);
01846       if (to > 0)
01847          to *= 1000;
01848       else {
01849          ast_log(LOG_WARNING, "Invalid timeout specified: '%s'. Setting timeout to infinite\n", args.timeout);
01850          to = -1;
01851       }
01852    }
01853 
01854    if (!outgoing) {
01855       strcpy(pa.status, "CHANUNAVAIL");
01856       if (fulldial == num_dialed) {
01857          res = -1;
01858          goto out;
01859       }
01860    } else {
01861       /* Our status will at least be NOANSWER */
01862       strcpy(pa.status, "NOANSWER");
01863       if (ast_test_flag64(outgoing, OPT_MUSICBACK)) {
01864          moh = 1;
01865          if (!ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
01866             char *original_moh = ast_strdupa(chan->musicclass);
01867             ast_string_field_set(chan, musicclass, opt_args[OPT_ARG_MUSICBACK]);
01868             ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
01869             ast_string_field_set(chan, musicclass, original_moh);
01870          } else {
01871             ast_moh_start(chan, NULL, NULL);
01872          }
01873          ast_indicate(chan, AST_CONTROL_PROGRESS);
01874       } else if (ast_test_flag64(outgoing, OPT_RINGBACK)) {
01875          ast_indicate(chan, AST_CONTROL_RINGING);
01876          sentringing++;
01877       }
01878    }
01879 
01880    peer = wait_for_answer(chan, outgoing, &to, peerflags, &pa, &num, &result);
01881 
01882    /* The ast_channel_datastore_remove() function could fail here if the
01883     * datastore was moved to another channel during a masquerade. If this is
01884     * the case, don't free the datastore here because later, when the channel
01885     * to which the datastore was moved hangs up, it will attempt to free this
01886     * datastore again, causing a crash
01887     */
01888    if (!ast_channel_datastore_remove(chan, datastore))
01889       ast_datastore_free(datastore);
01890    if (!peer) {
01891       if (result) {
01892          res = result;
01893       } else if (to) { /* Musta gotten hung up */
01894          res = -1;
01895       } else { /* Nobody answered, next please? */
01896          res = 0;
01897       }
01898 
01899       /* SIP, in particular, sends back this error code to indicate an
01900        * overlap dialled number needs more digits. */
01901       if (chan->hangupcause == AST_CAUSE_INVALID_NUMBER_FORMAT) {
01902          res = AST_PBX_INCOMPLETE;
01903       }
01904 
01905       /* almost done, although the 'else' block is 400 lines */
01906    } else {
01907       const char *number;
01908 
01909       strcpy(pa.status, "ANSWER");
01910       pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
01911       /* Ah ha!  Someone answered within the desired timeframe.  Of course after this
01912          we will always return with -1 so that it is hung up properly after the
01913          conversation.  */
01914       hanguptree(outgoing, peer, 1);
01915       outgoing = NULL;
01916       /* If appropriate, log that we have a destination channel */
01917       if (chan->cdr)
01918          ast_cdr_setdestchan(chan->cdr, peer->name);
01919       if (peer->name)
01920          pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", peer->name);
01921       
01922       ast_channel_lock(peer);
01923       number = pbx_builtin_getvar_helper(peer, "DIALEDPEERNUMBER"); 
01924       if (!number)
01925          number = numsubst;
01926       pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", number);
01927       ast_channel_unlock(peer);
01928 
01929       if (!ast_strlen_zero(args.url) && ast_channel_supports_html(peer) ) {
01930          ast_debug(1, "app_dial: sendurl=%s.\n", args.url);
01931          ast_channel_sendurl( peer, args.url );
01932       }
01933       if ( (ast_test_flag64(&opts, OPT_PRIVACY) || ast_test_flag64(&opts, OPT_SCREENING)) && pa.privdb_val == AST_PRIVACY_UNKNOWN) {
01934          if (do_privacy(chan, peer, &opts, opt_args, &pa)) {
01935             res = 0;
01936             goto out;
01937          }
01938       }
01939       if (!ast_test_flag64(&opts, OPT_ANNOUNCE) || ast_strlen_zero(opt_args[OPT_ARG_ANNOUNCE])) {
01940          res = 0;
01941       } else {
01942          int digit = 0;
01943          struct ast_channel *chans[2];
01944          struct ast_channel *active_chan;
01945 
01946          chans[0] = chan;
01947          chans[1] = peer;
01948 
01949          /* we need to stream the announcment while monitoring the caller for a hangup */
01950 
01951          /* stream the file */
01952          res = ast_streamfile(peer, opt_args[OPT_ARG_ANNOUNCE], peer->language);
01953          if (res) {
01954             res = 0;
01955             ast_log(LOG_ERROR, "error streaming file '%s' to callee\n", opt_args[OPT_ARG_ANNOUNCE]);
01956          }
01957 
01958          ast_set_flag(peer, AST_FLAG_END_DTMF_ONLY);
01959          while (peer->stream) {
01960             int ms;
01961 
01962             ms = ast_sched_wait(peer->sched);
01963 
01964             if (ms < 0 && !peer->timingfunc) {
01965                ast_stopstream(peer);
01966                break;
01967             }
01968             if (ms < 0)
01969                ms = 1000;
01970 
01971             active_chan = ast_waitfor_n(chans, 2, &ms);
01972             if (active_chan) {
01973                struct ast_frame *fr = ast_read(active_chan);
01974                if (!fr) {
01975                   ast_hangup(peer);
01976                   res = -1;
01977                   goto done;
01978                }
01979                switch(fr->frametype) {
01980                   case AST_FRAME_DTMF_END:
01981                      digit = fr->subclass;
01982                      if (active_chan == peer && strchr(AST_DIGIT_ANY, res)) {
01983                         ast_stopstream(peer);
01984                         res = ast_senddigit(chan, digit, 0);
01985                      }
01986                      break;
01987                   case AST_FRAME_CONTROL:
01988                      switch (fr->subclass) {
01989                         case AST_CONTROL_HANGUP:
01990                            ast_frfree(fr);
01991                            ast_hangup(peer);
01992                            res = -1;
01993                            goto done;
01994                         default:
01995                            break;
01996                      }
01997                      break;
01998                   default:
01999                      /* Ignore all others */
02000                      break;
02001                }
02002                ast_frfree(fr);
02003             }
02004             ast_sched_runq(peer->sched);
02005          }
02006          ast_clear_flag(peer, AST_FLAG_END_DTMF_ONLY);
02007       }
02008 
02009       if (chan && peer && ast_test_flag64(&opts, OPT_GOTO) && !ast_strlen_zero(opt_args[OPT_ARG_GOTO])) {
02010          replace_macro_delimiter(opt_args[OPT_ARG_GOTO]);
02011          ast_parseable_goto(chan, opt_args[OPT_ARG_GOTO]);
02012          /* peer goes to the same context and extension as chan, so just copy info from chan*/
02013          ast_copy_string(peer->context, chan->context, sizeof(peer->context));
02014          ast_copy_string(peer->exten, chan->exten, sizeof(peer->exten));
02015          peer->priority = chan->priority + 2;
02016          ast_pbx_start(peer);
02017          hanguptree(outgoing, NULL, ast_test_flag64(&opts, OPT_CANCEL_ELSEWHERE) ? 1 : 0);
02018          if (continue_exec)
02019             *continue_exec = 1;
02020          res = 0;
02021          goto done;
02022       }
02023 
02024       if (ast_test_flag64(&opts, OPT_CALLEE_MACRO) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_MACRO])) {
02025          struct ast_app *theapp;
02026          const char *macro_result;
02027 
02028          res = ast_autoservice_start(chan);
02029          if (res) {
02030             ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
02031             res = -1;
02032          }
02033 
02034          theapp = pbx_findapp("Macro");
02035 
02036          if (theapp && !res) { /* XXX why check res here ? */
02037             /* Set peer->exten and peer->context so that MACRO_EXTEN and MACRO_CONTEXT get set */
02038             ast_copy_string(peer->context, chan->context, sizeof(peer->context));
02039             ast_copy_string(peer->exten, chan->exten, sizeof(peer->exten));
02040 
02041             replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_MACRO]);
02042             res = pbx_exec(peer, theapp, opt_args[OPT_ARG_CALLEE_MACRO]);
02043             ast_debug(1, "Macro exited with status %d\n", res);
02044             res = 0;
02045          } else {
02046             ast_log(LOG_ERROR, "Could not find application Macro\n");
02047             res = -1;
02048          }
02049 
02050          if (ast_autoservice_stop(chan) < 0) {
02051             res = -1;
02052          }
02053 
02054          ast_channel_lock(peer);
02055 
02056          if (!res && (macro_result = pbx_builtin_getvar_helper(peer, "MACRO_RESULT"))) {
02057             char *macro_transfer_dest;
02058 
02059             if (!strcasecmp(macro_result, "BUSY")) {
02060                ast_copy_string(pa.status, macro_result, sizeof(pa.status));
02061                ast_set_flag64(peerflags, OPT_GO_ON);
02062                res = -1;
02063             } else if (!strcasecmp(macro_result, "CONGESTION") || !strcasecmp(macro_result, "CHANUNAVAIL")) {
02064                ast_copy_string(pa.status, macro_result, sizeof(pa.status));
02065                ast_set_flag64(peerflags, OPT_GO_ON);
02066                res = -1;
02067             } else if (!strcasecmp(macro_result, "CONTINUE")) {
02068                /* hangup peer and keep chan alive assuming the macro has changed
02069                   the context / exten / priority or perhaps
02070                   the next priority in the current exten is desired.
02071                */
02072                ast_set_flag64(peerflags, OPT_GO_ON);
02073                res = -1;
02074             } else if (!strcasecmp(macro_result, "ABORT")) {
02075                /* Hangup both ends unless the caller has the g flag */
02076                res = -1;
02077             } else if (!strncasecmp(macro_result, "GOTO:", 5) && (macro_transfer_dest = ast_strdupa(macro_result + 5))) {
02078                res = -1;
02079                /* perform a transfer to a new extension */
02080                if (strchr(macro_transfer_dest, '^')) { /* context^exten^priority*/
02081                   replace_macro_delimiter(macro_transfer_dest);
02082                   if (!ast_parseable_goto(chan, macro_transfer_dest))
02083                      ast_set_flag64(peerflags, OPT_GO_ON);
02084                }
02085             }
02086          }
02087 
02088          ast_channel_unlock(peer);
02089       }
02090 
02091       if (ast_test_flag64(&opts, OPT_CALLEE_GOSUB) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_GOSUB])) {
02092          struct ast_app *theapp;
02093          const char *gosub_result;
02094          char *gosub_args, *gosub_argstart;
02095          int res9 = -1;
02096 
02097          res9 = ast_autoservice_start(chan);
02098          if (res9) {
02099             ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
02100             res9 = -1;
02101          }
02102 
02103          theapp = pbx_findapp("Gosub");
02104 
02105          if (theapp && !res9) {
02106             replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_GOSUB]);
02107 
02108             /* Set where we came from */
02109             ast_copy_string(peer->context, "app_dial_gosub_virtual_context", sizeof(peer->context));
02110             ast_copy_string(peer->exten, "s", sizeof(peer->exten));
02111             peer->priority = 0;
02112 
02113             gosub_argstart = strchr(opt_args[OPT_ARG_CALLEE_GOSUB], ',');
02114             if (gosub_argstart) {
02115                *gosub_argstart = 0;
02116                if (asprintf(&gosub_args, "%s,s,1(%s)", opt_args[OPT_ARG_CALLEE_GOSUB], gosub_argstart + 1) < 0) {
02117                   ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
02118                   gosub_args = NULL;
02119                }
02120                *gosub_argstart = ',';
02121             } else {
02122                if (asprintf(&gosub_args, "%s,s,1", opt_args[OPT_ARG_CALLEE_GOSUB]) < 0) {
02123                   ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
02124                   gosub_args = NULL;
02125                }
02126             }
02127 
02128             if (gosub_args) {
02129                res9 = pbx_exec(peer, theapp, gosub_args);
02130                if (!res9) {
02131                   struct ast_pbx_args args;
02132                   /* A struct initializer fails to compile for this case ... */
02133                   memset(&args, 0, sizeof(args));
02134                   args.no_hangup_chan = 1;
02135                   ast_pbx_run_args(peer, &args);
02136                }
02137                ast_free(gosub_args);
02138                ast_debug(1, "Gosub exited with status %d\n", res9);
02139             } else {
02140                ast_log(LOG_ERROR, "Could not Allocate string for Gosub arguments -- Gosub Call Aborted!\n");
02141             }
02142 
02143          } else if (!res9) {
02144             ast_log(LOG_ERROR, "Could not find application Gosub\n");
02145             res9 = -1;
02146          }
02147 
02148          if (ast_autoservice_stop(chan) < 0) {
02149             ast_log(LOG_ERROR, "Could not stop autoservice on calling channel\n");
02150             res9 = -1;
02151          }
02152          
02153          ast_channel_lock(peer);
02154 
02155          if (!res9 && (gosub_result = pbx_builtin_getvar_helper(peer, "GOSUB_RESULT"))) {
02156             char *gosub_transfer_dest;
02157 
02158             if (!strcasecmp(gosub_result, "BUSY")) {
02159                ast_copy_string(pa.status, gosub_result, sizeof(pa.status));
02160                ast_set_flag64(peerflags, OPT_GO_ON);
02161                res = -1;
02162             } else if (!strcasecmp(gosub_result, "CONGESTION") || !strcasecmp(gosub_result, "CHANUNAVAIL")) {
02163                ast_copy_string(pa.status, gosub_result, sizeof(pa.status));
02164                ast_set_flag64(peerflags, OPT_GO_ON);
02165                res = -1;
02166             } else if (!strcasecmp(gosub_result, "CONTINUE")) {
02167                /* hangup peer and keep chan alive assuming the macro has changed
02168                   the context / exten / priority or perhaps
02169                   the next priority in the current exten is desired.
02170                */
02171                ast_set_flag64(peerflags, OPT_GO_ON);
02172                res = -1;
02173             } else if (!strcasecmp(gosub_result, "ABORT")) {
02174                /* Hangup both ends unless the caller has the g flag */
02175                res = -1;
02176             } else if (!strncasecmp(gosub_result, "GOTO:", 5) && (gosub_transfer_dest = ast_strdupa(gosub_result + 5))) {
02177                res = -1;
02178                /* perform a transfer to a new extension */
02179                if (strchr(gosub_transfer_dest, '^')) { /* context^exten^priority*/
02180                   replace_macro_delimiter(gosub_transfer_dest);
02181                   if (!ast_parseable_goto(chan, gosub_transfer_dest))
02182                      ast_set_flag64(peerflags, OPT_GO_ON);
02183                }
02184             }
02185          }
02186 
02187          ast_channel_unlock(peer);  
02188       }
02189 
02190       if (!res) {
02191          if (!ast_tvzero(calldurationlimit)) {
02192             struct timeval whentohangup = calldurationlimit;
02193             peer->whentohangup = ast_tvadd(ast_tvnow(), whentohangup);
02194          }
02195          if (!ast_strlen_zero(dtmfcalled)) {
02196             ast_verb(3, "Sending DTMF '%s' to the called party.\n", dtmfcalled);
02197             res = ast_dtmf_stream(peer, chan, dtmfcalled, 250, 0);
02198          }
02199          if (!ast_strlen_zero(dtmfcalling)) {
02200             ast_verb(3, "Sending DTMF '%s' to the calling party.\n", dtmfcalling);
02201             res = ast_dtmf_stream(chan, peer, dtmfcalling, 250, 0);
02202          }
02203       }
02204 
02205       if (res) { /* some error */
02206          res = -1;
02207       } else {
02208          if (ast_test_flag64(peerflags, OPT_CALLEE_TRANSFER))
02209             ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
02210          if (ast_test_flag64(peerflags, OPT_CALLER_TRANSFER))
02211             ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
02212          if (ast_test_flag64(peerflags, OPT_CALLEE_HANGUP))
02213             ast_set_flag(&(config.features_callee), AST_FEATURE_DISCONNECT);
02214          if (ast_test_flag64(peerflags, OPT_CALLER_HANGUP))
02215             ast_set_flag(&(config.features_caller), AST_FEATURE_DISCONNECT);
02216          if (ast_test_flag64(peerflags, OPT_CALLEE_MONITOR))
02217             ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMON);
02218          if (ast_test_flag64(peerflags, OPT_CALLER_MONITOR))
02219             ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMON);
02220          if (ast_test_flag64(peerflags, OPT_CALLEE_PARK))
02221             ast_set_flag(&(config.features_callee), AST_FEATURE_PARKCALL);
02222          if (ast_test_flag64(peerflags, OPT_CALLER_PARK))
02223             ast_set_flag(&(config.features_caller), AST_FEATURE_PARKCALL);
02224          if (ast_test_flag64(peerflags, OPT_CALLEE_MIXMONITOR))
02225             ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMIXMON);
02226          if (ast_test_flag64(peerflags, OPT_CALLER_MIXMONITOR))
02227             ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMIXMON);
02228          if (ast_test_flag64(peerflags, OPT_GO_ON))
02229             ast_set_flag(&(config.features_caller), AST_FEATURE_NO_H_EXTEN);
02230 
02231          config.end_bridge_callback = end_bridge_callback;
02232          config.end_bridge_callback_data = chan;
02233          config.end_bridge_callback_data_fixup = end_bridge_callback_data_fixup;
02234          
02235          if (moh) {
02236             moh = 0;
02237             ast_moh_stop(chan);
02238          } else if (sentringing) {
02239             sentringing = 0;
02240             ast_indicate(chan, -1);
02241          }
02242          /* Be sure no generators are left on it */
02243          ast_deactivate_generator(chan);
02244          /* Make sure channels are compatible */
02245          res = ast_channel_make_compatible(chan, peer);
02246          if (res < 0) {
02247             ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", chan->name, peer->name);
02248             ast_hangup(peer);
02249             res = -1;
02250             goto done;
02251          }
02252          if (opermode) {
02253             struct oprmode oprmode;
02254 
02255             oprmode.peer = peer;
02256             oprmode.mode = opermode;
02257 
02258             ast_channel_setoption(chan, AST_OPTION_OPRMODE, &oprmode, sizeof(oprmode), 0);
02259          }
02260          res = ast_bridge_call(chan, peer, &config);
02261       }
02262 
02263       strcpy(peer->context, chan->context);
02264 
02265       if (ast_test_flag64(&opts, OPT_PEER_H) && ast_exists_extension(peer, peer->context, "h", 1, peer->cid.cid_num)) {
02266          int autoloopflag;
02267          int found;
02268          int res9;
02269          
02270          strcpy(peer->exten, "h");
02271          peer->priority = 1;
02272          autoloopflag = ast_test_flag(peer, AST_FLAG_IN_AUTOLOOP); /* save value to restore at the end */
02273          ast_set_flag(peer, AST_FLAG_IN_AUTOLOOP);
02274 
02275          while ((res9 = ast_spawn_extension(peer, peer->context, peer->exten, peer->priority, peer->cid.cid_num, &found, 1)) == 0)
02276             peer->priority++;
02277 
02278          if (found && res9) {
02279             /* Something bad happened, or a hangup has been requested. */
02280             ast_debug(1, "Spawn extension (%s,%s,%d) exited non-zero on '%s'\n", peer->context, peer->exten, peer->priority, peer->name);
02281             ast_verb(2, "Spawn extension (%s, %s, %d) exited non-zero on '%s'\n", peer->context, peer->exten, peer->priority, peer->name);
02282          }
02283          ast_set2_flag(peer, autoloopflag, AST_FLAG_IN_AUTOLOOP);  /* set it back the way it was */
02284       }
02285       if (!ast_check_hangup(peer) && ast_test_flag64(&opts, OPT_CALLEE_GO_ON) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_GO_ON])) {      
02286          replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_GO_ON]);
02287          ast_parseable_goto(peer, opt_args[OPT_ARG_CALLEE_GO_ON]);
02288          ast_pbx_start(peer);
02289       } else {
02290          if (!ast_check_hangup(chan))
02291             chan->hangupcause = peer->hangupcause;
02292          ast_hangup(peer);
02293       }
02294    }
02295 out:
02296    if (moh) {
02297       moh = 0;
02298       ast_moh_stop(chan);
02299    } else if (sentringing) {
02300       sentringing = 0;
02301       ast_indicate(chan, -1);
02302    }
02303 
02304    if (delprivintro && ast_fileexists(pa.privintro, NULL, NULL) > 0) {
02305       ast_filedelete(pa.privintro, NULL);
02306       if (ast_fileexists(pa.privintro, NULL, NULL) > 0) {
02307          ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", pa.privintro);
02308       } else {
02309          ast_verb(3, "Successfully deleted %s intro file\n", pa.privintro);
02310       }
02311    }
02312 
02313    ast_channel_early_bridge(chan, NULL);
02314    hanguptree(outgoing, NULL, 0); /* In this case, there's no answer anywhere */
02315    pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
02316    senddialendevent(chan, pa.status);
02317    ast_debug(1, "Exiting with DIALSTATUS=%s.\n", pa.status);
02318    
02319    if ((ast_test_flag64(peerflags, OPT_GO_ON)) && !ast_check_hangup(chan) && (res != AST_PBX_INCOMPLETE)) {
02320       if (!ast_tvzero(calldurationlimit))
02321          memset(&chan->whentohangup, 0, sizeof(chan->whentohangup));
02322       res = 0;
02323    }
02324 
02325 done:
02326    if (config.warning_sound) {
02327       ast_free((char *)config.warning_sound);
02328    }
02329    if (config.end_sound) {
02330       ast_free((char *)config.end_sound);
02331    }
02332    if (config.start_sound) {
02333       ast_free((char *)config.start_sound);
02334    }
02335    return res;
02336 }
02337 
02338 static int dial_exec(struct ast_channel *chan, void *data)
02339 {
02340    struct ast_flags64 peerflags;
02341 
02342    memset(&peerflags, 0, sizeof(peerflags));
02343 
02344    return dial_exec_full(chan, data, &peerflags, NULL);
02345 }
02346 
02347 static int retrydial_exec(struct ast_channel *chan, void *data)
02348 {
02349    char *parse;
02350    const char *context = NULL;
02351    int sleepms = 0, loops = 0, res = -1;
02352    struct ast_flags64 peerflags = { 0, };
02353    AST_DECLARE_APP_ARGS(args,
02354       AST_APP_ARG(announce);
02355       AST_APP_ARG(sleep);
02356       AST_APP_ARG(retries);
02357       AST_APP_ARG(dialdata);
02358    );
02359 
02360    if (ast_strlen_zero(data)) {
02361       ast_log(LOG_WARNING, "RetryDial requires an argument!\n");
02362       return -1;
02363    }
02364 
02365    parse = ast_strdupa(data);
02366    AST_STANDARD_APP_ARGS(args, parse);
02367 
02368    if (!ast_strlen_zero(args.sleep) && (sleepms = atoi(args.sleep)))
02369       sleepms *= 1000;
02370 
02371    if (!ast_strlen_zero(args.retries)) {
02372       loops = atoi(args.retries);
02373    }
02374 
02375    if (!args.dialdata) {
02376       ast_log(LOG_ERROR, "%s requires a 4th argument (dialdata)\n", rapp);
02377       goto done;
02378    }
02379 
02380    if (sleepms < 1000)
02381       sleepms = 10000;
02382 
02383    if (!loops)
02384       loops = -1; /* run forever */
02385 
02386    ast_channel_lock(chan);
02387    context = pbx_builtin_getvar_helper(chan, "EXITCONTEXT");
02388    context = !ast_strlen_zero(context) ? ast_strdupa(context) : NULL;
02389    ast_channel_unlock(chan);
02390 
02391    res = 0;
02392    while (loops) {
02393       int continue_exec;
02394 
02395       chan->data = "Retrying";
02396       if (ast_test_flag(chan, AST_FLAG_MOH))
02397          ast_moh_stop(chan);
02398 
02399       res = dial_exec_full(chan, args.dialdata, &peerflags, &continue_exec);
02400       if (continue_exec)
02401          break;
02402 
02403       if (res == 0) {
02404          if (ast_test_flag64(&peerflags, OPT_DTMF_EXIT)) {
02405             if (!ast_strlen_zero(args.announce)) {
02406                if (ast_fileexists(args.announce, NULL, chan->language) > 0) {
02407                   if (!(res = ast_streamfile(chan, args.announce, chan->language)))
02408                      ast_waitstream(chan, AST_DIGIT_ANY);
02409                } else
02410                   ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", args.announce);
02411             }
02412             if (!res && sleepms) {
02413                if (!ast_test_flag(chan, AST_FLAG_MOH))
02414                   ast_moh_start(chan, NULL, NULL);
02415                res = ast_waitfordigit(chan, sleepms);
02416             }
02417          } else {
02418             if (!ast_strlen_zero(args.announce)) {
02419                if (ast_fileexists(args.announce, NULL, chan->language) > 0) {
02420                   if (!(res = ast_streamfile(chan, args.announce, chan->language)))
02421                      res = ast_waitstream(chan, "");
02422                } else
02423                   ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", args.announce);
02424             }
02425             if (sleepms) {
02426                if (!ast_test_flag(chan, AST_FLAG_MOH))
02427                   ast_moh_start(chan, NULL, NULL);
02428                if (!res)
02429                   res = ast_waitfordigit(chan, sleepms);
02430             }
02431          }
02432       }
02433 
02434       if (res < 0 || res == AST_PBX_INCOMPLETE) {
02435          break;
02436       } else if (res > 0) { /* Trying to send the call elsewhere (1 digit ext) */
02437          if (onedigit_goto(chan, context, (char) res, 1)) {
02438             res = 0;
02439             break;
02440          }
02441       }
02442       loops--;
02443    }
02444    if (loops == 0)
02445       res = 0;
02446    else if (res == 1)
02447       res = 0;
02448 
02449    if (ast_test_flag(chan, AST_FLAG_MOH))
02450       ast_moh_stop(chan);
02451  done:
02452    return res;
02453 }
02454 
02455 static int unload_module(void)
02456 {
02457    int res;
02458    struct ast_context *con;
02459 
02460    res = ast_unregister_application(app);
02461    res |= ast_unregister_application(rapp);
02462 
02463    if ((con = ast_context_find("app_dial_gosub_virtual_context"))) {
02464       ast_context_remove_extension2(con, "s", 1, NULL, 0);
02465       ast_context_destroy(con, "app_dial"); /* leave nothing behind */
02466    }
02467 
02468    return res;
02469 }
02470 
02471 static int load_module(void)
02472 {
02473    int res;
02474    struct ast_context *con;
02475 
02476    con = ast_context_find_or_create(NULL, NULL, "app_dial_gosub_virtual_context", "app_dial");
02477    if (!con)
02478       ast_log(LOG_ERROR, "Dial virtual context 'app_dial_gosub_virtual_context' does not exist and unable to create\n");
02479    else
02480       ast_add_extension2(con, 1, "s", 1, NULL, NULL, "NoOp", ast_strdup(""), ast_free_ptr, "app_dial");
02481 
02482    res = ast_register_application_xml(app, dial_exec);
02483    res |= ast_register_application_xml(rapp, retrydial_exec);
02484 
02485    return res;
02486 }
02487 
02488 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Dialing Application");