Sun Sep 7 06:28:33 2008

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 - 2006, 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: 135799 $")
00036 
00037 #include <stdlib.h>
00038 #include <errno.h>
00039 #include <unistd.h>
00040 #include <string.h>
00041 #include <stdlib.h>
00042 #include <stdio.h>
00043 #include <sys/time.h>
00044 #include <sys/signal.h>
00045 #include <sys/stat.h>
00046 #include <netinet/in.h>
00047 
00048 #include "asterisk/lock.h"
00049 #include "asterisk/file.h"
00050 #include "asterisk/logger.h"
00051 #include "asterisk/channel.h"
00052 #include "asterisk/pbx.h"
00053 #include "asterisk/options.h"
00054 #include "asterisk/module.h"
00055 #include "asterisk/translate.h"
00056 #include "asterisk/say.h"
00057 #include "asterisk/config.h"
00058 #include "asterisk/features.h"
00059 #include "asterisk/musiconhold.h"
00060 #include "asterisk/callerid.h"
00061 #include "asterisk/utils.h"
00062 #include "asterisk/app.h"
00063 #include "asterisk/causes.h"
00064 #include "asterisk/rtp.h"
00065 #include "asterisk/cdr.h"
00066 #include "asterisk/manager.h"
00067 #include "asterisk/privacy.h"
00068 #include "asterisk/stringfields.h"
00069 #include "asterisk/global_datastores.h"
00070 
00071 static char *app = "Dial";
00072 
00073 static char *synopsis = "Place a call and connect to the current channel";
00074 
00075 static char *descrip =
00076 "  Dial(Technology/resource[&Tech2/resource2...][|timeout][|options][|URL]):\n"
00077 "This application will place calls to one or more specified channels. As soon\n"
00078 "as one of the requested channels answers, the originating channel will be\n"
00079 "answered, if it has not already been answered. These two channels will then\n"
00080 "be active in a bridged call. All other channels that were requested will then\n"
00081 "be hung up.\n"
00082 "  Unless there is a timeout specified, the Dial application will wait\n"
00083 "indefinitely until one of the called channels answers, the user hangs up, or\n"
00084 "if all of the called channels are busy or unavailable. Dialplan executing will\n"
00085 "continue if no requested channels can be called, or if the timeout expires.\n\n"
00086 "  This application sets the following channel variables upon completion:\n"
00087 "    DIALEDTIME   - This is the time from dialing a channel until when it\n"
00088 "                   is disconnected.\n" 
00089 "    ANSWEREDTIME - This is the amount of time for actual call.\n"
00090 "    DIALSTATUS   - This is the status of the call:\n"
00091 "                   CHANUNAVAIL | CONGESTION | NOANSWER | BUSY | ANSWER | CANCEL\n" 
00092 "                   DONTCALL | TORTURE | INVALIDARGS\n"
00093 "  For the Privacy and Screening Modes, the DIALSTATUS variable will be set to\n"
00094 "DONTCALL if the called party chooses to send the calling party to the 'Go Away'\n"
00095 "script. The DIALSTATUS variable will be set to TORTURE if the called party\n"
00096 "wants to send the caller to the 'torture' script.\n"
00097 "  This application will report normal termination if the originating channel\n"
00098 "hangs up, or if the call is bridged and either of the parties in the bridge\n"
00099 "ends the call.\n"
00100 "  The optional URL will be sent to the called party if the channel supports it.\n"
00101 "  If the OUTBOUND_GROUP variable is set, all peer channels created by this\n"
00102 "application will be put into that group (as in Set(GROUP()=...).\n"
00103 "  If the OUTBOUND_GROUP_ONCE variable is set, all peer channels created by this\n"
00104 "application will be put into that group (as in Set(GROUP()=...). Unlike OUTBOUND_GROUP,\n"
00105 "however, the variable will be unset after use.\n\n"
00106 "  Options:\n"
00107 "    A(x) - Play an announcement to the called party, using 'x' as the file.\n"
00108 "    C    - Reset the CDR for this call.\n"
00109 "    d    - Allow the calling user to dial a 1 digit extension while waiting for\n"
00110 "           a call to be answered. Exit to that extension if it exists in the\n"
00111 "           current context, or the context defined in the EXITCONTEXT variable,\n"
00112 "           if it exists.\n"
00113 "    D([called][:calling]) - Send the specified DTMF strings *after* the called\n"
00114 "           party has answered, but before the call gets bridged. The 'called'\n"
00115 "           DTMF string is sent to the called party, and the 'calling' DTMF\n"
00116 "           string is sent to the calling party. Both parameters can be used\n"
00117 "           alone.\n"   
00118 "    f    - Force the callerid of the *calling* channel to be set as the\n"
00119 "           extension associated with the channel using a dialplan 'hint'.\n"
00120 "           For example, some PSTNs do not allow CallerID to be set to anything\n"
00121 "           other than the number assigned to the caller.\n"
00122 "    g    - Proceed with dialplan execution at the current extension if the\n"
00123 "           destination channel hangs up.\n"
00124 "    G(context^exten^pri) - If the call is answered, transfer the calling party to\n"
00125 "           the specified priority and the called party to the specified priority+1.\n"
00126 "           Optionally, an extension, or extension and context may be specified. \n"
00127 "           Otherwise, the current extension is used. You cannot use any additional\n"
00128 "           action post answer options in conjunction with this option.\n" 
00129 "    h    - Allow the called party to hang up by sending the '*' DTMF digit.\n"
00130 "    H    - Allow the calling party to hang up by hitting the '*' DTMF digit.\n"
00131 "    i    - Asterisk will ignore any forwarding requests it may receive on this\n"
00132 "           dial attempt.\n"
00133 "    j    - Jump to priority n+101 if all of the requested channels were busy.\n"
00134 "    k    - Allow the called party to enable parking of the call by sending\n"
00135 "           the DTMF sequence defined for call parking in features.conf.\n"
00136 "    K    - Allow the calling party to enable parking of the call by sending\n"
00137 "           the DTMF sequence defined for call parking in features.conf.\n"
00138 "    L(x[:y][:z]) - Limit the call to 'x' ms. Play a warning when 'y' ms are\n"
00139 "           left. Repeat the warning every 'z' ms. The following special\n"
00140 "           variables can be used with this option:\n"
00141 "           * LIMIT_PLAYAUDIO_CALLER   yes|no (default yes)\n"
00142 "                                      Play sounds to the caller.\n"
00143 "           * LIMIT_PLAYAUDIO_CALLEE   yes|no\n"
00144 "                                      Play sounds to the callee.\n"
00145 "           * LIMIT_TIMEOUT_FILE       File to play when time is up.\n"
00146 "           * LIMIT_CONNECT_FILE       File to play when call begins.\n"
00147 "           * LIMIT_WARNING_FILE       File to play as warning if 'y' is defined.\n"
00148 "                                      The default is to say the time remaining.\n"
00149 "    m([class]) - Provide hold music to the calling party until a requested\n"
00150 "           channel answers. A specific MusicOnHold class can be\n"
00151 "           specified.\n"
00152 "    M(x[^arg]) - Execute the Macro for the *called* channel before connecting\n"
00153 "           to the calling channel. Arguments can be specified to the Macro\n"
00154 "           using '^' as a delimeter. The Macro can set the variable\n"
00155 "           MACRO_RESULT to specify the following actions after the Macro is\n" 
00156 "           finished executing.\n"
00157 "           * ABORT        Hangup both legs of the call.\n"
00158 "           * CONGESTION   Behave as if line congestion was encountered.\n"
00159 "           * BUSY         Behave as if a busy signal was encountered. This will also\n"
00160 "                          have the application jump to priority n+101 if the\n"
00161 "                          'j' option is set.\n"
00162 "           * CONTINUE     Hangup the called party and allow the calling party\n"
00163 "                          to continue dialplan execution at the next priority.\n"
00164 "           * GOTO:<context>^<exten>^<priority> - Transfer the call to the\n"
00165 "                          specified priority. Optionally, an extension, or\n"
00166 "                          extension and priority can be specified.\n"
00167 "           You cannot use any additional action post answer options in conjunction\n"
00168 "           with this option. Also, pbx services are not run on the peer (called) channel,\n"
00169 "           so you will not be able to set timeouts via the TIMEOUT() function in this macro.\n"
00170 "    n    - This option is a modifier for the screen/privacy mode. It specifies\n"
00171 "           that no introductions are to be saved in the priv-callerintros\n"
00172 "           directory.\n"
00173 "    N    - This option is a modifier for the screen/privacy mode. It specifies\n"
00174 "           that if callerID is present, do not screen the call.\n"
00175 "    o    - Specify that the CallerID that was present on the *calling* channel\n"
00176 "           be set as the CallerID on the *called* channel. This was the\n"
00177 "           behavior of Asterisk 1.0 and earlier.\n"
00178 "    O([x]) - \"Operator Services\" mode (Zaptel channel to Zaptel channel\n"
00179 "             only, if specified on non-Zaptel interface, it will be ignored).\n"
00180 "             When the destination answers (presumably an operator services\n"
00181 "             station), the originator no longer has control of their line.\n"
00182 "             They may hang up, but the switch will not release their line\n"
00183 "             until the destination party hangs up (the operator). Specified\n"
00184 "             without an arg, or with 1 as an arg, the originator hanging up\n"
00185 "             will cause the phone to ring back immediately. With a 2 specified,\n"
00186 "             when the \"operator\" flashes the trunk, it will ring their phone\n"
00187 "             back.\n"
00188 "    p    - This option enables screening mode. This is basically Privacy mode\n"
00189 "           without memory.\n"
00190 "    P([x]) - Enable privacy mode. Use 'x' as the family/key in the database if\n"
00191 "           it is provided. The current extension is used if a database\n"
00192 "           family/key is not specified.\n"
00193 "    r    - Indicate ringing to the calling party. Pass no audio to the calling\n"
00194 "           party until the called channel has answered.\n"
00195 "    S(x) - Hang up the call after 'x' seconds *after* the called party has\n"
00196 "           answered the call.\n"   
00197 "    t    - Allow the called party to transfer the calling party by sending the\n"
00198 "           DTMF sequence defined in features.conf.\n"
00199 "    T    - Allow the calling party to transfer the called party by sending the\n"
00200 "           DTMF sequence defined in features.conf.\n"
00201 "    w    - Allow the called party to enable recording of the call by sending\n"
00202 "           the DTMF sequence defined for one-touch recording in features.conf.\n"
00203 "    W    - Allow the calling party to enable recording of the call by sending\n"
00204 "           the DTMF sequence defined for one-touch recording in features.conf.\n";
00205 
00206 /* RetryDial App by Anthony Minessale II <anthmct@yahoo.com> Jan/2005 */
00207 static char *rapp = "RetryDial";
00208 static char *rsynopsis = "Place a call, retrying on failure allowing optional exit extension.";
00209 static char *rdescrip =
00210 "  RetryDial(announce|sleep|retries|dialargs): This application will attempt to\n"
00211 "place a call using the normal Dial application. If no channel can be reached,\n"
00212 "the 'announce' file will be played. Then, it will wait 'sleep' number of\n"
00213 "seconds before retrying the call. After 'retries' number of attempts, the\n"
00214 "calling channel will continue at the next priority in the dialplan. If the\n"
00215 "'retries' setting is set to 0, this application will retry endlessly.\n"
00216 "  While waiting to retry a call, a 1 digit extension may be dialed. If that\n"
00217 "extension exists in either the context defined in ${EXITCONTEXT} or the current\n"
00218 "one, The call will jump to that extension immediately.\n"
00219 "  The 'dialargs' are specified in the same format that arguments are provided\n"
00220 "to the Dial application.\n";
00221 
00222 enum {
00223    OPT_ANNOUNCE =    (1 << 0),
00224    OPT_RESETCDR =    (1 << 1),
00225    OPT_DTMF_EXIT =      (1 << 2),
00226    OPT_SENDDTMF =    (1 << 3),
00227    OPT_FORCECLID =      (1 << 4),
00228    OPT_GO_ON =    (1 << 5),
00229    OPT_CALLEE_HANGUP =  (1 << 6),
00230    OPT_CALLER_HANGUP =  (1 << 7),
00231    OPT_PRIORITY_JUMP =  (1 << 8),
00232    OPT_DURATION_LIMIT = (1 << 9),
00233    OPT_MUSICBACK =      (1 << 10),
00234    OPT_CALLEE_MACRO =   (1 << 11),
00235    OPT_SCREEN_NOINTRO = (1 << 12),
00236    OPT_SCREEN_NOCLID =  (1 << 13),
00237    OPT_ORIGINAL_CLID =  (1 << 14),
00238    OPT_SCREENING =      (1 << 15),
00239    OPT_PRIVACY =     (1 << 16),
00240    OPT_RINGBACK =    (1 << 17),
00241    OPT_DURATION_STOP =  (1 << 18),
00242    OPT_CALLEE_TRANSFER =   (1 << 19),
00243    OPT_CALLER_TRANSFER =   (1 << 20),
00244    OPT_CALLEE_MONITOR = (1 << 21),
00245    OPT_CALLER_MONITOR = (1 << 22),
00246    OPT_GOTO =     (1 << 23),
00247    OPT_OPERMODE =       (1 << 24),
00248    OPT_CALLEE_PARK = (1 << 25),
00249    OPT_CALLER_PARK = (1 << 26),
00250    OPT_IGNORE_FORWARDING = (1 << 27),
00251 } dial_exec_option_flags;
00252 
00253 #define DIAL_STILLGOING       (1 << 30)
00254 #define DIAL_NOFORWARDHTML    (1 << 31)
00255 
00256 enum {
00257    OPT_ARG_ANNOUNCE = 0,
00258    OPT_ARG_SENDDTMF,
00259    OPT_ARG_GOTO,
00260    OPT_ARG_DURATION_LIMIT,
00261    OPT_ARG_MUSICBACK,
00262    OPT_ARG_CALLEE_MACRO,
00263    OPT_ARG_PRIVACY,
00264    OPT_ARG_DURATION_STOP,
00265    OPT_ARG_OPERMODE,
00266    /* note: this entry _MUST_ be the last one in the enum */
00267    OPT_ARG_ARRAY_SIZE,
00268 } dial_exec_option_args;
00269 
00270 AST_APP_OPTIONS(dial_exec_options, {
00271    AST_APP_OPTION_ARG('A', OPT_ANNOUNCE, OPT_ARG_ANNOUNCE),
00272    AST_APP_OPTION('C', OPT_RESETCDR),
00273    AST_APP_OPTION('d', OPT_DTMF_EXIT),
00274    AST_APP_OPTION_ARG('D', OPT_SENDDTMF, OPT_ARG_SENDDTMF),
00275    AST_APP_OPTION('f', OPT_FORCECLID),
00276    AST_APP_OPTION('g', OPT_GO_ON),
00277    AST_APP_OPTION_ARG('G', OPT_GOTO, OPT_ARG_GOTO),
00278    AST_APP_OPTION('h', OPT_CALLEE_HANGUP),
00279    AST_APP_OPTION('H', OPT_CALLER_HANGUP),
00280    AST_APP_OPTION('i', OPT_IGNORE_FORWARDING),
00281    AST_APP_OPTION('j', OPT_PRIORITY_JUMP),
00282    AST_APP_OPTION('k', OPT_CALLEE_PARK),
00283    AST_APP_OPTION('K', OPT_CALLER_PARK),
00284    AST_APP_OPTION_ARG('L', OPT_DURATION_LIMIT, OPT_ARG_DURATION_LIMIT),
00285    AST_APP_OPTION_ARG('m', OPT_MUSICBACK, OPT_ARG_MUSICBACK),
00286    AST_APP_OPTION_ARG('M', OPT_CALLEE_MACRO, OPT_ARG_CALLEE_MACRO),
00287    AST_APP_OPTION('n', OPT_SCREEN_NOINTRO),
00288    AST_APP_OPTION('N', OPT_SCREEN_NOCLID),
00289    AST_APP_OPTION('o', OPT_ORIGINAL_CLID),
00290    AST_APP_OPTION_ARG('O', OPT_OPERMODE,OPT_ARG_OPERMODE),
00291    AST_APP_OPTION('p', OPT_SCREENING),
00292    AST_APP_OPTION_ARG('P', OPT_PRIVACY, OPT_ARG_PRIVACY),
00293    AST_APP_OPTION('r', OPT_RINGBACK),
00294    AST_APP_OPTION_ARG('S', OPT_DURATION_STOP, OPT_ARG_DURATION_STOP),
00295    AST_APP_OPTION('t', OPT_CALLEE_TRANSFER),
00296    AST_APP_OPTION('T', OPT_CALLER_TRANSFER),
00297    AST_APP_OPTION('w', OPT_CALLEE_MONITOR),
00298    AST_APP_OPTION('W', OPT_CALLER_MONITOR),
00299 });
00300 
00301 #define CAN_EARLY_BRIDGE(flags,chan,peer) (!ast_test_flag(flags, OPT_CALLEE_HANGUP | \
00302    OPT_CALLER_HANGUP | OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER | \
00303    OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR | OPT_CALLEE_PARK | OPT_CALLER_PARK) && \
00304    !chan->audiohooks && !peer->audiohooks)
00305 
00306 /* We define a custom "local user" structure because we
00307    use it not only for keeping track of what is in use but
00308    also for keeping track of who we're dialing. */
00309 
00310 struct dial_localuser {
00311    struct ast_channel *chan;
00312    unsigned int flags;
00313    struct dial_localuser *next;
00314 };
00315 
00316 
00317 static void hanguptree(struct dial_localuser *outgoing, struct ast_channel *exception)
00318 {
00319    /* Hang up a tree of stuff */
00320    struct dial_localuser *oo;
00321    while (outgoing) {
00322       /* Hangup any existing lines we have open */
00323       if (outgoing->chan && (outgoing->chan != exception))
00324          ast_hangup(outgoing->chan);
00325       oo = outgoing;
00326       outgoing=outgoing->next;
00327       free(oo);
00328    }
00329 }
00330 
00331 #define AST_MAX_WATCHERS 256
00332 
00333 #define HANDLE_CAUSE(cause, chan) do { \
00334    switch(cause) { \
00335    case AST_CAUSE_BUSY: \
00336       if (chan->cdr) \
00337          ast_cdr_busy(chan->cdr); \
00338       numbusy++; \
00339       break; \
00340    case AST_CAUSE_CONGESTION: \
00341       if (chan->cdr) \
00342          ast_cdr_failed(chan->cdr); \
00343       numcongestion++; \
00344       break; \
00345    case AST_CAUSE_NO_ROUTE_DESTINATION: \
00346    case AST_CAUSE_UNREGISTERED: \
00347       if (chan->cdr) \
00348          ast_cdr_failed(chan->cdr); \
00349       numnochan++; \
00350       break; \
00351    case AST_CAUSE_NORMAL_CLEARING: \
00352       break; \
00353    default: \
00354       numnochan++; \
00355       break; \
00356    } \
00357 } while (0)
00358 
00359 
00360 static int onedigit_goto(struct ast_channel *chan, const char *context, char exten, int pri) 
00361 {
00362    char rexten[2] = { exten, '\0' };
00363 
00364    if (context) {
00365       if (!ast_goto_if_exists(chan, context, rexten, pri))
00366          return 1;
00367    } else {
00368       if (!ast_goto_if_exists(chan, chan->context, rexten, pri))
00369          return 1;
00370       else if (!ast_strlen_zero(chan->macrocontext)) {
00371          if (!ast_goto_if_exists(chan, chan->macrocontext, rexten, pri))
00372             return 1;
00373       }
00374    }
00375    return 0;
00376 }
00377 
00378 
00379 static const char *get_cid_name(char *name, int namelen, struct ast_channel *chan)
00380 {
00381    const char *context = S_OR(chan->macrocontext, chan->context);
00382    const char *exten = S_OR(chan->macroexten, chan->exten);
00383 
00384    return ast_get_hint(NULL, 0, name, namelen, chan, context, exten) ? name : "";
00385 }
00386 
00387 static void senddialevent(struct ast_channel *src, struct ast_channel *dst)
00388 {
00389    /* XXX do we need also CallerIDnum ? */
00390    manager_event(EVENT_FLAG_CALL, "Dial", 
00391             "Source: %s\r\n"
00392             "Destination: %s\r\n"
00393             "CallerID: %s\r\n"
00394             "CallerIDName: %s\r\n"
00395             "SrcUniqueID: %s\r\n"
00396             "DestUniqueID: %s\r\n",
00397             src->name, dst->name, S_OR(src->cid.cid_num, "<unknown>"),
00398             S_OR(src->cid.cid_name, "<unknown>"), src->uniqueid,
00399             dst->uniqueid);
00400 }
00401 
00402 static struct ast_channel *wait_for_answer(struct ast_channel *in, struct dial_localuser *outgoing, int *to, struct ast_flags *peerflags, int *sentringing, char *status, size_t statussize, int busystart, int nochanstart, int congestionstart, int priority_jump, int *result)
00403 {
00404    int numbusy = busystart;
00405    int numcongestion = congestionstart;
00406    int numnochan = nochanstart;
00407    int prestart = busystart + congestionstart + nochanstart;
00408    int orig = *to;
00409    struct ast_channel *peer = NULL;
00410    /* single is set if only one destination is enabled */
00411    int single = outgoing && !outgoing->next && !ast_test_flag(outgoing, OPT_MUSICBACK | OPT_RINGBACK);
00412    
00413    if (single) {
00414       /* Turn off hold music, etc */
00415       ast_deactivate_generator(in);
00416       /* If we are calling a single channel, make them compatible for in-band tone purpose */
00417       ast_channel_make_compatible(outgoing->chan, in);
00418    }
00419    
00420    
00421    while (*to && !peer) {
00422       struct dial_localuser *o;
00423       int pos = 0;   /* how many channels do we handle */
00424       int numlines = prestart;
00425       struct ast_channel *winner;
00426       struct ast_channel *watchers[AST_MAX_WATCHERS];
00427 
00428       watchers[pos++] = in;
00429       for (o = outgoing; o; o = o->next) {
00430          /* Keep track of important channels */
00431          if (ast_test_flag(o, DIAL_STILLGOING) && o->chan)
00432             watchers[pos++] = o->chan;
00433          numlines++;
00434       }
00435       if (pos == 1) {   /* only the input channel is available */
00436          if (numlines == (numbusy + numcongestion + numnochan)) {
00437             if (option_verbose > 2)
00438                ast_verbose( VERBOSE_PREFIX_2 "Everyone is busy/congested at this time (%d:%d/%d/%d)\n", numlines, numbusy, numcongestion, numnochan);
00439             if (numbusy)
00440                strcpy(status, "BUSY"); 
00441             else if (numcongestion)
00442                strcpy(status, "CONGESTION");
00443             else if (numnochan)
00444                strcpy(status, "CHANUNAVAIL");
00445             if (ast_opt_priority_jumping || priority_jump)
00446                ast_goto_if_exists(in, in->context, in->exten, in->priority + 101);
00447          } else {
00448             if (option_verbose > 2)
00449                ast_verbose(VERBOSE_PREFIX_3 "No one is available to answer at this time (%d:%d/%d/%d)\n", numlines, numbusy, numcongestion, numnochan);
00450          }
00451          *to = 0;
00452          return NULL;
00453       }
00454       winner = ast_waitfor_n(watchers, pos, to);
00455       for (o = outgoing; o; o = o->next) {
00456          struct ast_frame *f;
00457          struct ast_channel *c = o->chan;
00458 
00459          if (c == NULL)
00460             continue;
00461          if (ast_test_flag(o, DIAL_STILLGOING) && c->_state == AST_STATE_UP) {
00462             if (!peer) {
00463                if (option_verbose > 2)
00464                   ast_verbose(VERBOSE_PREFIX_3 "%s answered %s\n", c->name, in->name);
00465                peer = c;
00466                ast_copy_flags(peerflags, o,
00467                          OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
00468                          OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
00469                          OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
00470                          OPT_CALLEE_PARK | OPT_CALLER_PARK |
00471                          DIAL_NOFORWARDHTML);
00472                ast_copy_string(c->dialcontext, "", sizeof(c->dialcontext));
00473                ast_copy_string(c->exten, "", sizeof(c->exten));
00474             }
00475             continue;
00476          }
00477          if (c != winner)
00478             continue;
00479          if (!ast_strlen_zero(c->call_forward)) {
00480             char tmpchan[256];
00481             char *stuff;
00482             char *tech;
00483             int cause;
00484 
00485             ast_copy_string(tmpchan, c->call_forward, sizeof(tmpchan));
00486             if ((stuff = strchr(tmpchan, '/'))) {
00487                *stuff++ = '\0';
00488                tech = tmpchan;
00489             } else {
00490                const char *forward_context = pbx_builtin_getvar_helper(c, "FORWARD_CONTEXT");
00491                snprintf(tmpchan, sizeof(tmpchan), "%s@%s", c->call_forward, forward_context ? forward_context : c->context);
00492                stuff = tmpchan;
00493                tech = "Local";
00494             }
00495             /* Before processing channel, go ahead and check for forwarding */
00496             if (option_verbose > 2)
00497                ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, c->name);
00498             /* If we have been told to ignore forwards, just set this channel to null and continue processing extensions normally */
00499             if (ast_test_flag(peerflags, OPT_IGNORE_FORWARDING)) {
00500                if (option_verbose > 2)
00501                   ast_verbose(VERBOSE_PREFIX_3 "Forwarding %s to '%s/%s' prevented.\n", in->name, tech, stuff);
00502                c = o->chan = NULL;
00503                cause = AST_CAUSE_BUSY;
00504             } else {
00505                /* Setup parameters */
00506                if ((c = o->chan = ast_request(tech, in->nativeformats, stuff, &cause))) {
00507                   if (single)
00508                      ast_channel_make_compatible(o->chan, in);
00509                   ast_channel_inherit_variables(in, o->chan);
00510                   ast_channel_datastore_inherit(in, o->chan);
00511                } else
00512                   ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause);
00513             }
00514             if (!c) {
00515                ast_clear_flag(o, DIAL_STILLGOING); 
00516                HANDLE_CAUSE(cause, in);
00517             } else {
00518                ast_rtp_make_compatible(c, in, single);
00519                if (c->cid.cid_num)
00520                   free(c->cid.cid_num);
00521                c->cid.cid_num = NULL;
00522                if (c->cid.cid_name)
00523                   free(c->cid.cid_name);
00524                c->cid.cid_name = NULL;
00525 
00526                if (ast_test_flag(o, OPT_FORCECLID)) {
00527                   c->cid.cid_num = ast_strdup(S_OR(in->macroexten, in->exten));
00528                   ast_string_field_set(c, accountcode, winner->accountcode);
00529                   c->cdrflags = winner->cdrflags;
00530                } else {
00531                   c->cid.cid_num = ast_strdup(in->cid.cid_num);
00532                   c->cid.cid_name = ast_strdup(in->cid.cid_name);
00533                   ast_string_field_set(c, accountcode, in->accountcode);
00534                   c->cdrflags = in->cdrflags;
00535                }
00536 
00537                if (in->cid.cid_ani) {
00538                   if (c->cid.cid_ani)
00539                      free(c->cid.cid_ani);
00540                   c->cid.cid_ani = ast_strdup(in->cid.cid_ani);
00541                }
00542                if (c->cid.cid_rdnis) 
00543                   free(c->cid.cid_rdnis);
00544                c->cid.cid_rdnis = ast_strdup(S_OR(in->macroexten, in->exten));
00545                if (ast_call(c, tmpchan, 0)) {
00546                   ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
00547                   ast_clear_flag(o, DIAL_STILLGOING); 
00548                   ast_hangup(c);
00549                   c = o->chan = NULL;
00550                   numnochan++;
00551                } else {
00552                   senddialevent(in, c);
00553                   /* After calling, set callerid to extension */
00554                   if (!ast_test_flag(peerflags, OPT_ORIGINAL_CLID)) {
00555                      char cidname[AST_MAX_EXTENSION] = "";
00556                      ast_set_callerid(c, S_OR(in->macroexten, in->exten), get_cid_name(cidname, sizeof(cidname), in), NULL);
00557                   }
00558                }
00559             }
00560             /* Hangup the original channel now, in case we needed it */
00561             ast_hangup(winner);
00562             continue;
00563          }
00564          f = ast_read(winner);
00565          if (!f) {
00566             in->hangupcause = c->hangupcause;
00567             ast_hangup(c);
00568             c = o->chan = NULL;
00569             ast_clear_flag(o, DIAL_STILLGOING);
00570             HANDLE_CAUSE(in->hangupcause, in);
00571             continue;
00572          }
00573          if (f->frametype == AST_FRAME_CONTROL) {
00574             switch(f->subclass) {
00575             case AST_CONTROL_ANSWER:
00576                /* This is our guy if someone answered. */
00577                if (!peer) {
00578                   if (option_verbose > 2)
00579                      ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", c->name, in->name);
00580                   peer = c;
00581                   if (peer->cdr) {
00582                      peer->cdr->answer = ast_tvnow();
00583                      peer->cdr->disposition = AST_CDR_ANSWERED;
00584                   }
00585                   ast_copy_flags(peerflags, o,
00586                             OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
00587                             OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
00588                             OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
00589                             OPT_CALLEE_PARK | OPT_CALLER_PARK |
00590                             DIAL_NOFORWARDHTML);
00591                   ast_copy_string(c->dialcontext, "", sizeof(c->dialcontext));
00592                   ast_copy_string(c->exten, "", sizeof(c->exten));
00593                   /* Setup RTP early bridge if appropriate */
00594                   if (CAN_EARLY_BRIDGE(peerflags, in, peer))
00595                      ast_rtp_early_bridge(in, peer);
00596                }
00597                /* If call has been answered, then the eventual hangup is likely to be normal hangup */
00598                in->hangupcause = AST_CAUSE_NORMAL_CLEARING;
00599                c->hangupcause = AST_CAUSE_NORMAL_CLEARING;
00600                break;
00601             case AST_CONTROL_BUSY:
00602                if (option_verbose > 2)
00603                   ast_verbose(VERBOSE_PREFIX_3 "%s is busy\n", c->name);
00604                in->hangupcause = c->hangupcause;
00605                ast_hangup(c);
00606                c = o->chan = NULL;
00607                ast_clear_flag(o, DIAL_STILLGOING); 
00608                HANDLE_CAUSE(AST_CAUSE_BUSY, in);
00609                break;
00610             case AST_CONTROL_CONGESTION:
00611                if (option_verbose > 2)
00612                   ast_verbose(VERBOSE_PREFIX_3 "%s is circuit-busy\n", c->name);
00613                in->hangupcause = c->hangupcause;
00614                ast_hangup(c);
00615                c = o->chan = NULL;
00616                ast_clear_flag(o, DIAL_STILLGOING);
00617                HANDLE_CAUSE(AST_CAUSE_CONGESTION, in);
00618                break;
00619             case AST_CONTROL_RINGING:
00620                if (option_verbose > 2)
00621                   ast_verbose(VERBOSE_PREFIX_3 "%s is ringing\n", c->name);
00622                /* Setup early media if appropriate */
00623                if (single && CAN_EARLY_BRIDGE(peerflags, in, c))
00624                   ast_rtp_early_bridge(in, c);
00625                if (!(*sentringing) && !ast_test_flag(outgoing, OPT_MUSICBACK)) {
00626                   ast_indicate(in, AST_CONTROL_RINGING);
00627                   (*sentringing)++;
00628                }
00629                break;
00630             case AST_CONTROL_PROGRESS:
00631                if (option_verbose > 2)
00632                   ast_verbose (VERBOSE_PREFIX_3 "%s is making progress passing it to %s\n", c->name, in->name);
00633                /* Setup early media if appropriate */
00634                if (single && CAN_EARLY_BRIDGE(peerflags, in, c))
00635                   ast_rtp_early_bridge(in, c);
00636                if (!ast_test_flag(outgoing, OPT_RINGBACK))
00637                   ast_indicate(in, AST_CONTROL_PROGRESS);
00638                break;
00639             case AST_CONTROL_VIDUPDATE:
00640                if (option_verbose > 2)
00641                   ast_verbose (VERBOSE_PREFIX_3 "%s requested a video update, passing it to %s\n", c->name, in->name);
00642                ast_indicate(in, AST_CONTROL_VIDUPDATE);
00643                break;
00644             case AST_CONTROL_SRCUPDATE:
00645                if (option_verbose > 2)
00646                   ast_verbose (VERBOSE_PREFIX_3 "%s requested a source update, passing it to %s\n", c->name, in->name);
00647                ast_indicate(in, AST_CONTROL_SRCUPDATE);
00648                break;
00649             case AST_CONTROL_PROCEEDING:
00650                if (option_verbose > 2)
00651                   ast_verbose (VERBOSE_PREFIX_3 "%s is proceeding passing it to %s\n", c->name, in->name);
00652                if (single && CAN_EARLY_BRIDGE(peerflags, in, c))
00653                   ast_rtp_early_bridge(in, c);
00654                if (!ast_test_flag(outgoing, OPT_RINGBACK))
00655                   ast_indicate(in, AST_CONTROL_PROCEEDING);
00656                break;
00657             case AST_CONTROL_HOLD:
00658                if (option_verbose > 2)
00659                   ast_verbose(VERBOSE_PREFIX_3 "Call on %s placed on hold\n", c->name);
00660                ast_indicate(in, AST_CONTROL_HOLD);
00661                break;
00662             case AST_CONTROL_UNHOLD:
00663                if (option_verbose > 2)
00664                   ast_verbose(VERBOSE_PREFIX_3 "Call on %s left from hold\n", c->name);
00665                ast_indicate(in, AST_CONTROL_UNHOLD);
00666                break;
00667             case AST_CONTROL_OFFHOOK:
00668             case AST_CONTROL_FLASH:
00669                /* Ignore going off hook and flash */
00670                break;
00671             case -1:
00672                if (!ast_test_flag(outgoing, OPT_RINGBACK | OPT_MUSICBACK)) {
00673                   if (option_verbose > 2)
00674                      ast_verbose(VERBOSE_PREFIX_3 "%s stopped sounds\n", c->name);
00675                   ast_indicate(in, -1);
00676                   (*sentringing) = 0;
00677                }
00678                break;
00679             default:
00680                if (option_debug)
00681                   ast_log(LOG_DEBUG, "Dunno what to do with control type %d\n", f->subclass);
00682             }
00683          } else if (single) {
00684             /* XXX are we sure the logic is correct ? or we should just switch on f->frametype ? */
00685             if (f->frametype == AST_FRAME_VOICE && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
00686                if (ast_write(in, f)) 
00687                   ast_log(LOG_WARNING, "Unable to forward voice frame\n");
00688             } else if (f->frametype == AST_FRAME_IMAGE && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
00689                if (ast_write(in, f))
00690                   ast_log(LOG_WARNING, "Unable to forward image\n");
00691             } else if (f->frametype == AST_FRAME_TEXT && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
00692                if (ast_write(in, f))
00693                   ast_log(LOG_WARNING, "Unable to send text\n");
00694             } else if (f->frametype == AST_FRAME_HTML && !ast_test_flag(outgoing, DIAL_NOFORWARDHTML)) {
00695                if (ast_channel_sendhtml(in, f->subclass, f->data, f->datalen) == -1)
00696                   ast_log(LOG_WARNING, "Unable to send URL\n");
00697             }
00698          }
00699          ast_frfree(f);
00700       } /* end for */
00701       if (winner == in) {
00702          struct ast_frame *f = ast_read(in);
00703 #if 0
00704          if (f && (f->frametype != AST_FRAME_VOICE))
00705             printf("Frame type: %d, %d\n", f->frametype, f->subclass);
00706          else if (!f || (f->frametype != AST_FRAME_VOICE))
00707             printf("Hangup received on %s\n", in->name);
00708 #endif
00709          if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
00710             /* Got hung up */
00711             *to = -1;
00712             ast_cdr_noanswer(in->cdr);
00713             strcpy(status, "CANCEL");
00714             if (f)
00715                ast_frfree(f);
00716             return NULL;
00717          }
00718 
00719          if (f && (f->frametype == AST_FRAME_DTMF)) {
00720             if (ast_test_flag(peerflags, OPT_DTMF_EXIT)) {
00721                const char *context = pbx_builtin_getvar_helper(in, "EXITCONTEXT");
00722                if (onedigit_goto(in, context, (char) f->subclass, 1)) {
00723                   if (option_verbose > 2)
00724                      ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
00725                   *to=0;
00726                   ast_cdr_noanswer(in->cdr);
00727                   *result = f->subclass;
00728                   strcpy(status, "CANCEL");
00729                   ast_frfree(f);
00730                   return NULL;
00731                }
00732             }
00733 
00734             if (ast_test_flag(peerflags, OPT_CALLER_HANGUP) && 
00735                     (f->subclass == '*')) { /* hmm it it not guaranteed to be '*' anymore. */
00736                if (option_verbose > 2)
00737                   ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
00738                *to=0;
00739                ast_cdr_noanswer(in->cdr);
00740                strcpy(status, "CANCEL");
00741                ast_frfree(f);
00742                return NULL;
00743             }
00744          }
00745 
00746          /* Forward HTML stuff */
00747          if (single && f && (f->frametype == AST_FRAME_HTML) && !ast_test_flag(outgoing, DIAL_NOFORWARDHTML)) 
00748             if(ast_channel_sendhtml(outgoing->chan, f->subclass, f->data, f->datalen) == -1)
00749                ast_log(LOG_WARNING, "Unable to send URL\n");
00750          
00751 
00752          if (single && ((f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_DTMF_BEGIN) || (f->frametype == AST_FRAME_DTMF_END)))  {
00753             if (ast_write(outgoing->chan, f))
00754                ast_log(LOG_WARNING, "Unable to forward voice or dtmf\n");
00755          }
00756          if (single && (f->frametype == AST_FRAME_CONTROL) && 
00757             ((f->subclass == AST_CONTROL_HOLD) || 
00758              (f->subclass == AST_CONTROL_UNHOLD) || 
00759              (f->subclass == AST_CONTROL_VIDUPDATE) ||
00760              (f->subclass == AST_CONTROL_SRCUPDATE))) {
00761             if (option_verbose > 2)
00762                ast_verbose(VERBOSE_PREFIX_3 "%s requested special control %d, passing it to %s\n", in->name, f->subclass, outgoing->chan->name);
00763             ast_indicate_data(outgoing->chan, f->subclass, f->data, f->datalen);
00764          }
00765          ast_frfree(f);
00766       }
00767       if (!*to && (option_verbose > 2))
00768          ast_verbose(VERBOSE_PREFIX_3 "Nobody picked up in %d ms\n", orig);
00769       if (!*to || ast_check_hangup(in)) {
00770          ast_cdr_noanswer(in->cdr);
00771       }
00772       
00773    }
00774    
00775    return peer;
00776 }
00777 
00778 static void replace_macr