00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
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
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
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
00307
00308
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
00320 struct dial_localuser *oo;
00321 while (outgoing) {
00322
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
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
00411 int single = outgoing && !outgoing->next && !ast_test_flag(outgoing, OPT_MUSICBACK | OPT_RINGBACK);
00412
00413 if (single) {
00414
00415 ast_deactivate_generator(in);
00416
00417 ast_channel_make_compatible(outgoing->chan, in);
00418 }
00419
00420
00421 while (*to && !peer) {
00422 struct dial_localuser *o;
00423 int pos = 0;
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
00431 if (ast_test_flag(o, DIAL_STILLGOING) && o->chan)
00432 watchers[pos++] = o->chan;
00433 numlines++;
00434 }
00435 if (pos == 1) {
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
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
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
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
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
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
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
00594 if (CAN_EARLY_BRIDGE(peerflags, in, peer))
00595 ast_rtp_early_bridge(in, peer);
00596 }
00597
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
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
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
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
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 }
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
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 == '*')) {
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
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