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 #include "asterisk.h"
00029
00030 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 75405 $")
00031
00032 #include <stdlib.h>
00033 #include <errno.h>
00034 #include <unistd.h>
00035 #include <string.h>
00036 #include <stdlib.h>
00037 #include <stdio.h>
00038 #include <sys/time.h>
00039 #include <sys/signal.h>
00040 #include <sys/stat.h>
00041 #include <netinet/in.h>
00042
00043 #include "asterisk/lock.h"
00044 #include "asterisk/file.h"
00045 #include "asterisk/logger.h"
00046 #include "asterisk/channel.h"
00047 #include "asterisk/pbx.h"
00048 #include "asterisk/options.h"
00049 #include "asterisk/module.h"
00050 #include "asterisk/translate.h"
00051 #include "asterisk/say.h"
00052 #include "asterisk/config.h"
00053 #include "asterisk/features.h"
00054 #include "asterisk/musiconhold.h"
00055 #include "asterisk/callerid.h"
00056 #include "asterisk/utils.h"
00057 #include "asterisk/app.h"
00058 #include "asterisk/causes.h"
00059 #include "asterisk/rtp.h"
00060 #include "asterisk/manager.h"
00061 #include "asterisk/privacy.h"
00062 #include "asterisk/stringfields.h"
00063
00064 static char *app = "Dial";
00065
00066 static char *synopsis = "Place a call and connect to the current channel";
00067
00068 static char *descrip =
00069 " Dial(Technology/resource[&Tech2/resource2...][|timeout][|options][|URL]):\n"
00070 "This application will place calls to one or more specified channels. As soon\n"
00071 "as one of the requested channels answers, the originating channel will be\n"
00072 "answered, if it has not already been answered. These two channels will then\n"
00073 "be active in a bridged call. All other channels that were requested will then\n"
00074 "be hung up.\n"
00075 " Unless there is a timeout specified, the Dial application will wait\n"
00076 "indefinitely until one of the called channels answers, the user hangs up, or\n"
00077 "if all of the called channels are busy or unavailable. Dialplan executing will\n"
00078 "continue if no requested channels can be called, or if the timeout expires.\n\n"
00079 " This application sets the following channel variables upon completion:\n"
00080 " DIALEDTIME - This is the time from dialing a channel until when it\n"
00081 " is disconnected.\n"
00082 " ANSWEREDTIME - This is the amount of time for actual call.\n"
00083 " DIALSTATUS - This is the status of the call:\n"
00084 " CHANUNAVAIL | CONGESTION | NOANSWER | BUSY | ANSWER | CANCEL\n"
00085 " DONTCALL | TORTURE | INVALIDARGS\n"
00086 " For the Privacy and Screening Modes, the DIALSTATUS variable will be set to\n"
00087 "DONTCALL if the called party chooses to send the calling party to the 'Go Away'\n"
00088 "script. The DIALSTATUS variable will be set to TORTURE if the called party\n"
00089 "wants to send the caller to the 'torture' script.\n"
00090 " This application will report normal termination if the originating channel\n"
00091 "hangs up, or if the call is bridged and either of the parties in the bridge\n"
00092 "ends the call.\n"
00093 " The optional URL will be sent to the called party if the channel supports it.\n"
00094 " If the OUTBOUND_GROUP variable is set, all peer channels created by this\n"
00095 "application will be put into that group (as in Set(GROUP()=...).\n"
00096 " If the OUTBOUND_GROUP_ONCE variable is set, all peer channels created by this\n"
00097 "application will be put into that group (as in Set(GROUP()=...). Unlike OUTBOUND_GROUP,\n"
00098 "however, the variable will be unset after use.\n\n"
00099 " Options:\n"
00100 " A(x) - Play an announcement to the called party, using 'x' as the file.\n"
00101 " C - Reset the CDR for this call.\n"
00102 " d - Allow the calling user to dial a 1 digit extension while waiting for\n"
00103 " a call to be answered. Exit to that extension if it exists in the\n"
00104 " current context, or the context defined in the EXITCONTEXT variable,\n"
00105 " if it exists.\n"
00106 " D([called][:calling]) - Send the specified DTMF strings *after* the called\n"
00107 " party has answered, but before the call gets bridged. The 'called'\n"
00108 " DTMF string is sent to the called party, and the 'calling' DTMF\n"
00109 " string is sent to the calling party. Both parameters can be used\n"
00110 " alone.\n"
00111 " f - Force the callerid of the *calling* channel to be set as the\n"
00112 " extension associated with the channel using a dialplan 'hint'.\n"
00113 " For example, some PSTNs do not allow CallerID to be set to anything\n"
00114 " other than the number assigned to the caller.\n"
00115 " g - Proceed with dialplan execution at the current extension if the\n"
00116 " destination channel hangs up.\n"
00117 " G(context^exten^pri) - If the call is answered, transfer the calling party to\n"
00118 " the specified priority and the called party to the specified priority+1.\n"
00119 " Optionally, an extension, or extension and context may be specified. \n"
00120 " Otherwise, the current extension is used. You cannot use any additional\n"
00121 " action post answer options in conjunction with this option.\n"
00122 " h - Allow the called party to hang up by sending the '*' DTMF digit.\n"
00123 " H - Allow the calling party to hang up by hitting the '*' DTMF digit.\n"
00124 " i - Asterisk will ignore any forwarding requests it may receive on this\n"
00125 " dial attempt.\n"
00126 " j - Jump to priority n+101 if all of the requested channels were busy.\n"
00127 " L(x[:y][:z]) - Limit the call to 'x' ms. Play a warning when 'y' ms are\n"
00128 " left. Repeat the warning every 'z' ms. The following special\n"
00129 " variables can be used with this option:\n"
00130 " * LIMIT_PLAYAUDIO_CALLER yes|no (default yes)\n"
00131 " Play sounds to the caller.\n"
00132 " * LIMIT_PLAYAUDIO_CALLEE yes|no\n"
00133 " Play sounds to the callee.\n"
00134 " * LIMIT_TIMEOUT_FILE File to play when time is up.\n"
00135 " * LIMIT_CONNECT_FILE File to play when call begins.\n"
00136 " * LIMIT_WARNING_FILE File to play as warning if 'y' is defined.\n"
00137 " The default is to say the time remaining.\n"
00138 " m([class]) - Provide hold music to the calling party until a requested\n"
00139 " channel answers. A specific MusicOnHold class can be\n"
00140 " specified.\n"
00141 " M(x[^arg]) - Execute the Macro for the *called* channel before connecting\n"
00142 " to the calling channel. Arguments can be specified to the Macro\n"
00143 " using '^' as a delimeter. The Macro can set the variable\n"
00144 " MACRO_RESULT to specify the following actions after the Macro is\n"
00145 " finished executing.\n"
00146 " * ABORT Hangup both legs of the call.\n"
00147 " * CONGESTION Behave as if line congestion was encountered.\n"
00148 " * BUSY Behave as if a busy signal was encountered. This will also\n"
00149 " have the application jump to priority n+101 if the\n"
00150 " 'j' option is set.\n"
00151 " * CONTINUE Hangup the called party and allow the calling party\n"
00152 " to continue dialplan execution at the next priority.\n"
00153 " * GOTO:<context>^<exten>^<priority> - Transfer the call to the\n"
00154 " specified priority. Optionally, an extension, or\n"
00155 " extension and priority can be specified.\n"
00156 " You cannot use any additional action post answer options in conjunction\n"
00157 " with this option. Also, pbx services are not run on the peer (called) channel,\n"
00158 " so you will not be able to set timeouts via the TIMEOUT() function in this macro.\n"
00159 " n - This option is a modifier for the screen/privacy mode. It specifies\n"
00160 " that no introductions are to be saved in the priv-callerintros\n"
00161 " directory.\n"
00162 " N - This option is a modifier for the screen/privacy mode. It specifies\n"
00163 " that if callerID is present, do not screen the call.\n"
00164 " o - Specify that the CallerID that was present on the *calling* channel\n"
00165 " be set as the CallerID on the *called* channel. This was the\n"
00166 " behavior of Asterisk 1.0 and earlier.\n"
00167 " O([x]) - \"Operator Services\" mode (Zaptel channel to Zaptel channel\n"
00168 " only, if specified on non-Zaptel interface, it will be ignored).\n"
00169 " When the destination answers (presumably an operator services\n"
00170 " station), the originator no longer has control of their line.\n"
00171 " They may hang up, but the switch will not release their line\n"
00172 " until the destination party hangs up (the operator). Specified\n"
00173 " without an arg, or with 1 as an arg, the originator hanging up\n"
00174 " will cause the phone to ring back immediately. With a 2 specified,\n"
00175 " when the \"operator\" flashes the trunk, it will ring their phone\n"
00176 " back.\n"
00177 " p - This option enables screening mode. This is basically Privacy mode\n"
00178 " without memory.\n"
00179 " P([x]) - Enable privacy mode. Use 'x' as the family/key in the database if\n"
00180 " it is provided. The current extension is used if a database\n"
00181 " family/key is not specified.\n"
00182 " r - Indicate ringing to the calling party. Pass no audio to the calling\n"
00183 " party until the called channel has answered.\n"
00184 " S(x) - Hang up the call after 'x' seconds *after* the called party has\n"
00185 " answered the call.\n"
00186 " t - Allow the called party to transfer the calling party by sending the\n"
00187 " DTMF sequence defined in features.conf.\n"
00188 " T - Allow the calling party to transfer the called party by sending the\n"
00189 " DTMF sequence defined in features.conf.\n"
00190 " w - Allow the called party to enable recording of the call by sending\n"
00191 " the DTMF sequence defined for one-touch recording in features.conf.\n"
00192 " W - Allow the calling party to enable recording of the call by sending\n"
00193 " the DTMF sequence defined for one-touch recording in features.conf.\n"
00194 " k - Allow the called party to enable parking of the call by sending\n"
00195 " the DTMF sequence defined for call parking in features.conf.\n"
00196 " K - Allow the calling party to enable parking of the call by sending\n"
00197 " the DTMF sequence defined for call parking in features.conf.\n";
00198
00199
00200 static char *rapp = "RetryDial";
00201 static char *rsynopsis = "Place a call, retrying on failure allowing optional exit extension.";
00202 static char *rdescrip =
00203 " RetryDial(announce|sleep|retries|dialargs): This application will attempt to\n"
00204 "place a call using the normal Dial application. If no channel can be reached,\n"
00205 "the 'announce' file will be played. Then, it will wait 'sleep' number of\n"
00206 "seconds before retying the call. After 'retires' number of attempts, the\n"
00207 "calling channel will continue at the next priority in the dialplan. If the\n"
00208 "'retries' setting is set to 0, this application will retry endlessly.\n"
00209 " While waiting to retry a call, a 1 digit extension may be dialed. If that\n"
00210 "extension exists in either the context defined in ${EXITCONTEXT} or the current\n"
00211 "one, The call will jump to that extension immediately.\n"
00212 " The 'dialargs' are specified in the same format that arguments are provided\n"
00213 "to the Dial application.\n";
00214
00215 enum {
00216 OPT_ANNOUNCE = (1 << 0),
00217 OPT_RESETCDR = (1 << 1),
00218 OPT_DTMF_EXIT = (1 << 2),
00219 OPT_SENDDTMF = (1 << 3),
00220 OPT_FORCECLID = (1 << 4),
00221 OPT_GO_ON = (1 << 5),
00222 OPT_CALLEE_HANGUP = (1 << 6),
00223 OPT_CALLER_HANGUP = (1 << 7),
00224 OPT_PRIORITY_JUMP = (1 << 8),
00225 OPT_DURATION_LIMIT = (1 << 9),
00226 OPT_MUSICBACK = (1 << 10),
00227 OPT_CALLEE_MACRO = (1 << 11),
00228 OPT_SCREEN_NOINTRO = (1 << 12),
00229 OPT_SCREEN_NOCLID = (1 << 13),
00230 OPT_ORIGINAL_CLID = (1 << 14),
00231 OPT_SCREENING = (1 << 15),
00232 OPT_PRIVACY = (1 << 16),
00233 OPT_RINGBACK = (1 << 17),
00234 OPT_DURATION_STOP = (1 << 18),
00235 OPT_CALLEE_TRANSFER = (1 << 19),
00236 OPT_CALLER_TRANSFER = (1 << 20),
00237 OPT_CALLEE_MONITOR = (1 << 21),
00238 OPT_CALLER_MONITOR = (1 << 22),
00239 OPT_GOTO = (1 << 23),
00240 OPT_OPERMODE = (1 << 24),
00241 OPT_CALLEE_PARK = (1 << 25),
00242 OPT_CALLER_PARK = (1 << 26),
00243 OPT_IGNORE_FORWARDING = (1 << 27),
00244 } dial_exec_option_flags;
00245
00246 #define DIAL_STILLGOING (1 << 30)
00247 #define DIAL_NOFORWARDHTML (1 << 31)
00248
00249 enum {
00250 OPT_ARG_ANNOUNCE = 0,
00251 OPT_ARG_SENDDTMF,
00252 OPT_ARG_GOTO,
00253 OPT_ARG_DURATION_LIMIT,
00254 OPT_ARG_MUSICBACK,
00255 OPT_ARG_CALLEE_MACRO,
00256 OPT_ARG_PRIVACY,
00257 OPT_ARG_DURATION_STOP,
00258 OPT_ARG_OPERMODE,
00259
00260 OPT_ARG_ARRAY_SIZE,
00261 } dial_exec_option_args;
00262
00263 AST_APP_OPTIONS(dial_exec_options, {
00264 AST_APP_OPTION_ARG('A', OPT_ANNOUNCE, OPT_ARG_ANNOUNCE),
00265 AST_APP_OPTION('C', OPT_RESETCDR),
00266 AST_APP_OPTION('d', OPT_DTMF_EXIT),
00267 AST_APP_OPTION_ARG('D', OPT_SENDDTMF, OPT_ARG_SENDDTMF),
00268 AST_APP_OPTION('f', OPT_FORCECLID),
00269 AST_APP_OPTION('g', OPT_GO_ON),
00270 AST_APP_OPTION_ARG('G', OPT_GOTO, OPT_ARG_GOTO),
00271 AST_APP_OPTION('h', OPT_CALLEE_HANGUP),
00272 AST_APP_OPTION('H', OPT_CALLER_HANGUP),
00273 AST_APP_OPTION('i', OPT_IGNORE_FORWARDING),
00274 AST_APP_OPTION('j', OPT_PRIORITY_JUMP),
00275 AST_APP_OPTION_ARG('L', OPT_DURATION_LIMIT, OPT_ARG_DURATION_LIMIT),
00276 AST_APP_OPTION_ARG('m', OPT_MUSICBACK, OPT_ARG_MUSICBACK),
00277 AST_APP_OPTION_ARG('M', OPT_CALLEE_MACRO, OPT_ARG_CALLEE_MACRO),
00278 AST_APP_OPTION('n', OPT_SCREEN_NOINTRO),
00279 AST_APP_OPTION('N', OPT_SCREEN_NOCLID),
00280 AST_APP_OPTION_ARG('O', OPT_OPERMODE,OPT_ARG_OPERMODE),
00281 AST_APP_OPTION('o', OPT_ORIGINAL_CLID),
00282 AST_APP_OPTION('p', OPT_SCREENING),
00283 AST_APP_OPTION_ARG('P', OPT_PRIVACY, OPT_ARG_PRIVACY),
00284 AST_APP_OPTION('r', OPT_RINGBACK),
00285 AST_APP_OPTION_ARG('S', OPT_DURATION_STOP, OPT_ARG_DURATION_STOP),
00286 AST_APP_OPTION('t', OPT_CALLEE_TRANSFER),
00287 AST_APP_OPTION('T', OPT_CALLER_TRANSFER),
00288 AST_APP_OPTION('w', OPT_CALLEE_MONITOR),
00289 AST_APP_OPTION('W', OPT_CALLER_MONITOR),
00290 AST_APP_OPTION('k', OPT_CALLEE_PARK),
00291 AST_APP_OPTION('K', OPT_CALLER_PARK),
00292 });
00293
00294
00295
00296
00297
00298 struct dial_localuser {
00299 struct ast_channel *chan;
00300 unsigned int flags;
00301 int forwards;
00302 struct dial_localuser *next;
00303 };
00304
00305
00306 static void hanguptree(struct dial_localuser *outgoing, struct ast_channel *exception)
00307 {
00308
00309 struct dial_localuser *oo;
00310 while (outgoing) {
00311
00312 if (outgoing->chan && (outgoing->chan != exception))
00313 ast_hangup(outgoing->chan);
00314 oo = outgoing;
00315 outgoing=outgoing->next;
00316 free(oo);
00317 }
00318 }
00319
00320 #define AST_MAX_FORWARDS 8
00321
00322 #define AST_MAX_WATCHERS 256
00323
00324 #define HANDLE_CAUSE(cause, chan) do { \
00325 switch(cause) { \
00326 case AST_CAUSE_BUSY: \
00327 if (chan->cdr) \
00328 ast_cdr_busy(chan->cdr); \
00329 numbusy++; \
00330 break; \
00331 case AST_CAUSE_CONGESTION: \
00332 if (chan->cdr) \
00333 ast_cdr_failed(chan->cdr); \
00334 numcongestion++; \
00335 break; \
00336 case AST_CAUSE_UNREGISTERED: \
00337 if (chan->cdr) \
00338 ast_cdr_failed(chan->cdr); \
00339 numnochan++; \
00340 break; \
00341 case AST_CAUSE_NORMAL_CLEARING: \
00342 break; \
00343 default: \
00344 numnochan++; \
00345 break; \
00346 } \
00347 } while (0)
00348
00349
00350 static int onedigit_goto(struct ast_channel *chan, const char *context, char exten, int pri)
00351 {
00352 char rexten[2] = { exten, '\0' };
00353
00354 if (context) {
00355 if (!ast_goto_if_exists(chan, context, rexten, pri))
00356 return 1;
00357 } else {
00358 if (!ast_goto_if_exists(chan, chan->context, rexten, pri))
00359 return 1;
00360 else if (!ast_strlen_zero(chan->macrocontext)) {
00361 if (!ast_goto_if_exists(chan, chan->macrocontext, rexten, pri))
00362 return 1;
00363 }
00364 }
00365 return 0;
00366 }
00367
00368
00369 static const char *get_cid_name(char *name, int namelen, struct ast_channel *chan)
00370 {
00371 const char *context = S_OR(chan->macrocontext, chan->context);
00372 const char *exten = S_OR(chan->macroexten, chan->exten);
00373
00374 return ast_get_hint(NULL, 0, name, namelen, chan, context, exten) ? name : "";
00375 }
00376
00377 static void senddialevent(struct ast_channel *src, struct ast_channel *dst)
00378 {
00379
00380 manager_event(EVENT_FLAG_CALL, "Dial",
00381 "Source: %s\r\n"
00382 "Destination: %s\r\n"
00383 "CallerID: %s\r\n"
00384 "CallerIDName: %s\r\n"
00385 "SrcUniqueID: %s\r\n"
00386 "DestUniqueID: %s\r\n",
00387 src->name, dst->name, S_OR(src->cid.cid_num, "<unknown>"),
00388 S_OR(src->cid.cid_name, "<unknown>"), src->uniqueid,
00389 dst->uniqueid);
00390 }
00391
00392 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)
00393 {
00394 int numbusy = busystart;
00395 int numcongestion = congestionstart;
00396 int numnochan = nochanstart;
00397 int prestart = busystart + congestionstart + nochanstart;
00398 int orig = *to;
00399 struct ast_channel *peer = NULL;
00400
00401 int single = outgoing && !outgoing->next && !ast_test_flag(outgoing, OPT_MUSICBACK | OPT_RINGBACK);
00402
00403 if (single) {
00404
00405 ast_deactivate_generator(in);
00406
00407 ast_channel_make_compatible(outgoing->chan, in);
00408 }
00409
00410
00411 while (*to && !peer) {
00412 struct dial_localuser *o;
00413 int pos = 0;
00414 int numlines = prestart;
00415 struct ast_channel *winner;
00416 struct ast_channel *watchers[AST_MAX_WATCHERS];
00417
00418 watchers[pos++] = in;
00419 for (o = outgoing; o; o = o->next) {
00420
00421 if (ast_test_flag(o, DIAL_STILLGOING) && o->chan)
00422 watchers[pos++] = o->chan;
00423 numlines++;
00424 }
00425 if (pos == 1) {
00426 if (numlines == (numbusy + numcongestion + numnochan)) {
00427 if (option_verbose > 2)
00428 ast_verbose( VERBOSE_PREFIX_2 "Everyone is busy/congested at this time (%d:%d/%d/%d)\n", numlines, numbusy, numcongestion, numnochan);
00429 if (numbusy)
00430 strcpy(status, "BUSY");
00431 else if (numcongestion)
00432 strcpy(status, "CONGESTION");
00433 else if (numnochan)
00434 strcpy(status, "CHANUNAVAIL");
00435 if (ast_opt_priority_jumping || priority_jump)
00436 ast_goto_if_exists(in, in->context, in->exten, in->priority + 101);
00437 } else {
00438 if (option_verbose > 2)
00439 ast_verbose(VERBOSE_PREFIX_3 "No one is available to answer at this time (%d:%d/%d/%d)\n", numlines, numbusy, numcongestion, numnochan);
00440 }
00441 *to = 0;
00442 return NULL;
00443 }
00444 winner = ast_waitfor_n(watchers, pos, to);
00445 for (o = outgoing; o; o = o->next) {
00446 struct ast_frame *f;
00447 struct ast_channel *c = o->chan;
00448
00449 if (c == NULL)
00450 continue;
00451 if (ast_test_flag(o, DIAL_STILLGOING) && c->_state == AST_STATE_UP) {
00452 if (!peer) {
00453 if (option_verbose > 2)
00454 ast_verbose(VERBOSE_PREFIX_3 "%s answered %s\n", c->name, in->name);
00455 peer = c;
00456 ast_copy_flags(peerflags, o,
00457 OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
00458 OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
00459 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
00460 OPT_CALLEE_PARK | OPT_CALLER_PARK |
00461 DIAL_NOFORWARDHTML);
00462 ast_copy_string(c->dialcontext, "", sizeof(c->dialcontext));
00463 ast_copy_string(c->exten, "", sizeof(c->exten));
00464 }
00465 continue;
00466 }
00467 if (c != winner)
00468 continue;
00469 if (!ast_strlen_zero(c->call_forward)) {
00470 char tmpchan[256];
00471 char *stuff;
00472 char *tech;
00473 int cause;
00474
00475 ast_copy_string(tmpchan, c->call_forward, sizeof(tmpchan));
00476 if ((stuff = strchr(tmpchan, '/'))) {
00477 *stuff++ = '\0';
00478 tech = tmpchan;
00479 } else {
00480 const char *forward_context = pbx_builtin_getvar_helper(c, "FORWARD_CONTEXT");
00481 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", c->call_forward, forward_context ? forward_context : c->context);
00482 stuff = tmpchan;
00483 tech = "Local";
00484 }
00485
00486 o->forwards++;
00487 if (o->forwards < AST_MAX_FORWARDS) {
00488 if (option_verbose > 2)
00489 ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, c->name);
00490
00491 if (ast_test_flag(peerflags, OPT_IGNORE_FORWARDING)) {
00492 if (option_verbose > 2)
00493 ast_verbose(VERBOSE_PREFIX_3 "Forwarding %s to '%s/%s' prevented.\n", in->name, tech, stuff);
00494 c = o->chan = NULL;
00495 cause = AST_CAUSE_BUSY;
00496 } else {
00497
00498 if ((c = o->chan = ast_request(tech, in->nativeformats, stuff, &cause))) {
00499 if (single)
00500 ast_channel_make_compatible(o->chan, in);
00501 ast_channel_inherit_variables(in, o->chan);
00502 } else
00503 ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause);
00504 }
00505 } else {
00506 if (option_verbose > 2)
00507 ast_verbose(VERBOSE_PREFIX_3 "Too many forwards from %s\n", c->name);
00508 cause = AST_CAUSE_CONGESTION;
00509 c = o->chan = NULL;
00510 }
00511 if (!c) {
00512 ast_clear_flag(o, DIAL_STILLGOING);
00513 HANDLE_CAUSE(cause, in);
00514 } else {
00515 ast_rtp_make_compatible(c, in, single);
00516 if (c->cid.cid_num)
00517 free(c->cid.cid_num);
00518 c->cid.cid_num = NULL;
00519 if (c->cid.cid_name)
00520 free(c->cid.cid_name);
00521 c->cid.cid_name = NULL;
00522
00523 if (ast_test_flag(o, OPT_FORCECLID)) {
00524 c->cid.cid_num = ast_strdup(S_OR(in->macroexten, in->exten));
00525 ast_string_field_set(c, accountcode, winner->accountcode);
00526 c->cdrflags = winner->cdrflags;
00527 } else {
00528 c->cid.cid_num = ast_strdup(in->cid.cid_num);
00529 c->cid.cid_name = ast_strdup(in->cid.cid_name);
00530 ast_string_field_set(c, accountcode, in->accountcode);
00531 c->cdrflags = in->cdrflags;
00532 }
00533
00534 if (in->cid.cid_ani) {
00535 if (c->cid.cid_ani)
00536 free(c->cid.cid_ani);
00537 c->cid.cid_ani = ast_strdup(in->cid.cid_ani);
00538 }
00539 if (c->cid.cid_rdnis)
00540 free(c->cid.cid_rdnis);
00541 c->cid.cid_rdnis = ast_strdup(S_OR(in->macroexten, in->exten));
00542 if (ast_call(c, tmpchan, 0)) {
00543 ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
00544 ast_clear_flag(o, DIAL_STILLGOING);
00545 ast_hangup(c);
00546 c = o->chan = NULL;
00547 numnochan++;
00548 } else {
00549 senddialevent(in, c);
00550
00551 if (!ast_test_flag(peerflags, OPT_ORIGINAL_CLID)) {
00552 char cidname[AST_MAX_EXTENSION] = "";
00553 ast_set_callerid(c, S_OR(in->macroexten, in->exten), get_cid_name(cidname, sizeof(cidname), in), NULL);
00554 }
00555 }
00556 }
00557
00558 ast_hangup(winner);
00559 continue;
00560 }
00561 f = ast_read(winner);
00562 if (!f) {
00563 in->hangupcause = c->hangupcause;
00564 ast_hangup(c);
00565 c = o->chan = NULL;
00566 ast_clear_flag(o, DIAL_STILLGOING);
00567 HANDLE_CAUSE(in->hangupcause, in);
00568 continue;
00569 }
00570 if (f->frametype == AST_FRAME_CONTROL) {
00571 switch(f->subclass) {
00572 case AST_CONTROL_ANSWER:
00573
00574 if (!peer) {
00575 if (option_verbose > 2)
00576 ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", c->name, in->name);
00577 peer = c;
00578 ast_copy_flags(peerflags, o,
00579 OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
00580 OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
00581 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
00582 OPT_CALLEE_PARK | OPT_CALLER_PARK |
00583 DIAL_NOFORWARDHTML);
00584 ast_copy_string(c->dialcontext, "", sizeof(c->dialcontext));
00585 ast_copy_string(c->exten, "", sizeof(c->exten));
00586
00587 ast_rtp_early_bridge(in, peer);
00588 }
00589
00590 in->hangupcause = AST_CAUSE_NORMAL_CLEARING;
00591 c->hangupcause = AST_CAUSE_NORMAL_CLEARING;
00592 break;
00593 case AST_CONTROL_BUSY:
00594 if (option_verbose > 2)
00595 ast_verbose(VERBOSE_PREFIX_3 "%s is busy\n", c->name);
00596 in->hangupcause = c->hangupcause;
00597 ast_hangup(c);
00598 c = o->chan = NULL;
00599 ast_clear_flag(o, DIAL_STILLGOING);
00600 HANDLE_CAUSE(AST_CAUSE_BUSY, in);
00601 break;
00602 case AST_CONTROL_CONGESTION:
00603 if (option_verbose > 2)
00604 ast_verbose(VERBOSE_PREFIX_3 "%s is circuit-busy\n", c->name);
00605 in->hangupcause = c->hangupcause;
00606 ast_hangup(c);
00607 c = o->chan = NULL;
00608 ast_clear_flag(o, DIAL_STILLGOING);
00609 HANDLE_CAUSE(AST_CAUSE_CONGESTION, in);
00610 break;
00611 case AST_CONTROL_RINGING:
00612 if (option_verbose > 2)
00613 ast_verbose(VERBOSE_PREFIX_3 "%s is ringing\n", c->name);
00614
00615 if (single)
00616 ast_rtp_early_bridge(in, c);
00617 if (!(*sentringing) && !ast_test_flag(outgoing, OPT_MUSICBACK)) {
00618 ast_indicate(in, AST_CONTROL_RINGING);
00619 (*sentringing)++;
00620 }
00621 break;
00622 case AST_CONTROL_PROGRESS:
00623 if (option_verbose > 2)
00624 ast_verbose (VERBOSE_PREFIX_3 "%s is making progress passing it to %s\n", c->name, in->name);
00625
00626 if (single)
00627 ast_rtp_early_bridge(in, c);
00628 if (!ast_test_flag(outgoing, OPT_RINGBACK))
00629 ast_indicate(in, AST_CONTROL_PROGRESS);
00630 break;
00631 case AST_CONTROL_VIDUPDATE:
00632 if (option_verbose > 2)
00633 ast_verbose (VERBOSE_PREFIX_3 "%s requested a video update, passing it to %s\n", c->name, in->name);
00634 ast_indicate(in, AST_CONTROL_VIDUPDATE);
00635 break;
00636 case AST_CONTROL_PROCEEDING:
00637 if (option_verbose > 2)
00638 ast_verbose (VERBOSE_PREFIX_3 "%s is proceeding passing it to %s\n", c->name, in->name);
00639 if (single)
00640 ast_rtp_early_bridge(in, c);
00641 if (!ast_test_flag(outgoing, OPT_RINGBACK))
00642 ast_indicate(in, AST_CONTROL_PROCEEDING);
00643 break;
00644 case AST_CONTROL_HOLD:
00645 if (option_verbose > 2)
00646 ast_verbose(VERBOSE_PREFIX_3 "Call on %s placed on hold\n", c->name);
00647 ast_indicate(in, AST_CONTROL_HOLD);
00648 break;
00649 case AST_CONTROL_UNHOLD:
00650 if (option_verbose > 2)
00651 ast_verbose(VERBOSE_PREFIX_3 "Call on %s left from hold\n", c->name);
00652 ast_indicate(in, AST_CONTROL_UNHOLD);
00653 break;
00654 case AST_CONTROL_OFFHOOK:
00655 case AST_CONTROL_FLASH:
00656
00657 break;
00658 case -1:
00659 if (!ast_test_flag(outgoing, OPT_RINGBACK | OPT_MUSICBACK)) {
00660 if (option_verbose > 2)
00661 ast_verbose(VERBOSE_PREFIX_3 "%s stopped sounds\n", c->name);
00662 ast_indicate(in, -1);
00663 (*sentringing) = 0;
00664 }
00665 break;
00666 default:
00667 if (option_debug)
00668 ast_log(LOG_DEBUG, "Dunno what to do with control type %d\n", f->subclass);
00669 }
00670 } else if (single) {
00671
00672 if (f->frametype == AST_FRAME_VOICE && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
00673 if (ast_write(in, f))
00674 ast_log(LOG_WARNING, "Unable to forward voice frame\n");
00675 } else if (f->frametype == AST_FRAME_IMAGE && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
00676 if (ast_write(in, f))
00677 ast_log(LOG_WARNING, "Unable to forward image\n");
00678 } else if (f->frametype == AST_FRAME_TEXT && !ast_test_flag(outgoing, OPT_RINGBACK|OPT_MUSICBACK)) {
00679 if (ast_write(in, f))
00680 ast_log(LOG_WARNING, "Unable to send text\n");
00681 } else if (f->frametype == AST_FRAME_HTML && !ast_test_flag(outgoing, DIAL_NOFORWARDHTML)) {
00682 if (ast_channel_sendhtml(in, f->subclass, f->data, f->datalen) == -1)
00683 ast_log(LOG_WARNING, "Unable to send URL\n");
00684 }
00685 }
00686 ast_frfree(f);
00687 }
00688 if (winner == in) {
00689 struct ast_frame *f = ast_read(in);
00690 #if 0
00691 if (f && (f->frametype != AST_FRAME_VOICE))
00692 printf("Frame type: %d, %d\n", f->frametype, f->subclass);
00693 else if (!f || (f->frametype != AST_FRAME_VOICE))
00694 printf("Hangup received on %s\n", in->name);
00695 #endif
00696 if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
00697
00698 *to = -1;
00699 ast_cdr_noanswer(in->cdr);
00700 strcpy(status, "CANCEL");
00701 if (f)
00702 ast_frfree(f);
00703 return NULL;
00704 }
00705
00706 if (f && (f->frametype == AST_FRAME_DTMF)) {
00707 if (ast_test_flag(peerflags, OPT_DTMF_EXIT)) {
00708 const char *context = pbx_builtin_getvar_helper(in, "EXITCONTEXT");
00709 if (onedigit_goto(in, context, (char) f->subclass, 1)) {
00710 if (option_verbose > 2)
00711 ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
00712 *to=0;
00713 ast_cdr_noanswer(in->cdr);
00714 *result = f->subclass;
00715 strcpy(status, "CANCEL");
00716 ast_frfree(f);
00717 return NULL;
00718 }
00719 }
00720
00721 if (ast_test_flag(peerflags, OPT_CALLER_HANGUP) &&
00722 (f->subclass == '*')) {
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 strcpy(status, "CANCEL");
00728 ast_frfree(f);
00729 return NULL;
00730 }
00731 }
00732
00733
00734 if (single && f && (f->frametype == AST_FRAME_HTML) && !ast_test_flag(outgoing, DIAL_NOFORWARDHTML))
00735 if(ast_channel_sendhtml(outgoing->chan, f->subclass, f->data, f->datalen) == -1)
00736 ast_log(LOG_WARNING, "Unable to send URL\n");
00737
00738
00739 if (single && ((f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_DTMF_BEGIN) || (f->frametype == AST_FRAME_DTMF_END))) {
00740 if (ast_write(outgoing->chan, f))
00741 ast_log(LOG_WARNING, "Unable to forward voice or dtmf\n");
00742 }
00743 if (single && (f->frametype == AST_FRAME_CONTROL) &&
00744 ((f->subclass == AST_CONTROL_HOLD) ||
00745 (f->subclass == AST_CONTROL_UNHOLD) ||
00746 (f->subclass == AST_CONTROL_VIDUPDATE))) {
00747 if (option_verbose > 2)
00748 ast_verbose(VERBOSE_PREFIX_3 "%s requested special control %d, passing it to %s\n", in->name, f->subclass, outgoing->chan->name);
00749 ast_indicate_data(outgoing->chan, f->subclass, f->data, f->datalen);
00750 }
00751 ast_frfree(f);
00752 }
00753 if (!*to && (option_verbose > 2))
00754 ast_verbose(VERBOSE_PREFIX_3 "Nobody picked up in %d ms\n", orig);
00755 if (!*to || ast_check_hangup(in)) {
00756 ast_cdr_noanswer(in->cdr);
00757 }
00758
00759 }
00760
00761 return peer;
00762 }
00763
00764 static void replace_macro_delimiter(char *s)
00765 {
00766 for (; *s; s++)
00767 if (*s == '^')
00768 *s = '|';
00769 }
00770
00771
00772
00773 static int valid_priv_reply(struct ast_flags *opts, int res)
00774 {
00775 if (res < '1')
00776 return 0;
00777 if (ast_test_flag(opts, OPT_PRIVACY) && res <= '5')
00778 return 1;
00779 if (ast_test_flag(opts, OPT_SCREENING) && res <= '4')
00780 return 1;
00781 return 0;
00782 }
00783
00784 static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags *peerflags, int *continue_exec)
00785 {
00786 int res = -1;
00787 struct ast_module_user *u;
00788 char *rest, *cur;
00789 struct dial_localuser *outgoing = NULL;
00790 struct ast_channel *peer;
00791 int to;
00792 int numbusy = 0;
00793 int numcongestion = 0;
00794 int numnochan = 0;
00795 int cause;
00796 char numsubst[256];
00797 char cidname[AST_MAX_EXTENSION] = "";
00798 int privdb_val = 0;
00799 unsigned int calldurationlimit = 0;
00800 long timelimit = 0;
00801 long play_warning = 0;
00802 long warning_freq = 0;
00803 const char *warning_sound = NULL;
00804 const char *end_sound = NULL;
00805 const char *start_sound = NULL;
00806 char *dtmfcalled = NULL, *dtmfcalling = NULL;
00807 char status[256] = "INVALIDARGS";
00808 int play_to_caller = 0, play_to_callee = 0;
00809 int sentringing = 0, moh = 0;
00810 const char *outbound_group = NULL;
00811 int result = 0;
00812 time_t start_time;
00813 char privintro[1024];
00814 char privcid[256];
00815 char *parse;
00816 int opermode = 0;
00817 AST_DECLARE_APP_ARGS(args,
00818 AST_APP_ARG(peers);
00819 AST_APP_ARG(timeout);
00820 AST_APP_ARG(options);
00821 AST_APP_ARG(url);
00822 );
00823 struct ast_flags opts = { 0, };
00824 char *opt_args[OPT_ARG_ARRAY_SIZE];
00825
00826 if (ast_strlen_zero(data)) {
00827 ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
00828 pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
00829 return -1;
00830 }
00831
00832 u = ast_module_user_add(chan);
00833
00834 parse = ast_strdupa(data);
00835
00836 AST_STANDARD_APP_ARGS(args, parse);
00837
00838 if (!ast_strlen_zero(args.options) &&
00839 ast_app_parse_options(dial_exec_options, &opts, opt_args, args.options)) {
00840 pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
00841 goto done;
00842 }
00843
00844 if (ast_strlen_zero(args.peers)) {
00845 ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
00846 pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
00847 goto done;
00848 }
00849
00850 if (ast_test_flag(&opts, OPT_OPERMODE)) {
00851 if (ast_strlen_zero(opt_args[OPT_ARG_OPERMODE]))
00852 opermode = 1;
00853 else opermode = atoi(opt_args[OPT_ARG_OPERMODE]);
00854 if (option_verbose > 2)
00855 ast_verbose(VERBOSE_PREFIX_3 "Setting operator services mode to %d.\n", opermode);
00856 }
00857
00858 if (ast_test_flag(&opts, OPT_DURATION_STOP) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_STOP])) {
00859 calldurationlimit = atoi(opt_args[OPT_ARG_DURATION_STOP]);
00860 if (!calldurationlimit) {
00861 ast_log(LOG_WARNING, "Dial does not accept S(%s), hanging up.\n", opt_args[OPT_ARG_DURATION_STOP]);
00862 pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
00863 goto done;
00864 }
00865 if (option_verbose > 2)
00866 ast_verbose(VERBOSE_PREFIX_3 "Setting call duration limit to %d seconds.\n", calldurationlimit);
00867 }
00868
00869 if (ast_test_flag(&opts, OPT_SENDDTMF) && !ast_strlen_zero(opt_args[OPT_ARG_SENDDTMF])) {
00870 dtmfcalling = opt_args[OPT_ARG_SENDDTMF];
00871 dtmfcalled = strsep(&dtmfcalling, ":");
00872 }
00873
00874 if (ast_test_flag(&opts, OPT_DURATION_LIMIT) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_LIMIT])) {
00875 char *limit_str, *warning_str, *warnfreq_str;
00876 const char *var;
00877
00878 warnfreq_str = opt_args[OPT_ARG_DURATION_LIMIT];
00879 limit_str = strsep(&warnfreq_str, ":");
00880 warning_str = strsep(&warnfreq_str, ":");
00881
00882 timelimit = atol(limit_str);
00883 if (warning_str)
00884 play_warning = atol(warning_str);
00885 if (warnfreq_str)
00886 warning_freq = atol(warnfreq_str);
00887
00888 if (!timelimit) {
00889 ast_log(LOG_WARNING, "Dial does not accept L(%s), hanging up.\n", limit_str);
00890 goto done;
00891 } else if (play_warning > timelimit) {
00892
00893
00894
00895
00896
00897
00898 if (!warning_freq) {
00899 play_warning = 0;
00900 } else {
00901
00902 while (play_warning > timelimit)
00903 play_warning -= warning_freq;
00904 if (play_warning < 1)
00905 play_warning = warning_freq = 0;
00906 }
00907 }
00908
00909 var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLER");
00910 play_to_caller = var ? ast_true(var) : 1;
00911
00912 var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLEE");
00913 play_to_callee = var ? ast_true(var) : 0;
00914
00915 if (!play_to_caller && !play_to_callee)
00916 play_to_caller = 1;
00917
00918 var = pbx_builtin_getvar_helper(chan,"LIMIT_WARNING_FILE");
00919 warning_sound = S_OR(var, "timeleft");
00920
00921 var = pbx_builtin_getvar_helper(chan,"LIMIT_TIMEOUT_FILE");
00922 end_sound = S_OR(var, NULL);
00923
00924 var = pbx_builtin_getvar_helper(chan,"LIMIT_CONNECT_FILE");
00925 start_sound = S_OR(var, NULL);
00926
00927
00928 calldurationlimit = 0;
00929
00930 if (!play_warning && !start_sound && !end_sound && timelimit) {
00931 calldurationlimit = timelimit / 1000;
00932 if (option_verbose > 2)
00933 ast_verbose(VERBOSE_PREFIX_3 "Setting call duration limit to %d seconds.\n", calldurationlimit);
00934 timelimit = play_to_caller = play_to_callee = play_warning = warning_freq = 0;
00935 } else if (option_verbose > 2) {
00936 ast_verbose(VERBOSE_PREFIX_3 "Limit Data for this call:\n");
00937 ast_verbose(VERBOSE_PREFIX_4 "timelimit = %ld\n", timelimit);
00938 ast_verbose(VERBOSE_PREFIX_4 "play_warning = %ld\n", play_warning);
00939 ast_verbose(VERBOSE_PREFIX_4 "play_to_caller = %s\n", play_to_caller ? "yes" : "no");
00940 ast_verbose(VERBOSE_PREFIX_4 "play_to_callee = %s\n", play_to_callee ? "yes" : "no");
00941 ast_verbose(VERBOSE_PREFIX_4 "warning_freq = %ld\n", warning_freq);
00942 ast_verbose(VERBOSE_PREFIX_4 "start_sound = %s\n", start_sound);
00943 ast_verbose(VERBOSE_PREFIX_4 "warning_sound = %s\n", warning_sound);
00944 ast_verbose(VERBOSE_PREFIX_4 "end_sound = %s\n", end_sound);
00945 }
00946 }
00947
00948 if (ast_test_flag(&opts, OPT_RESETCDR) && chan->cdr)
00949 ast_cdr_reset(chan->cdr, NULL);
00950 if (ast_test_flag(&opts, OPT_PRIVACY) && ast_strlen_zero(opt_args[OPT_ARG_PRIVACY]))
00951 opt_args[OPT_ARG_PRIVACY] = ast_strdupa(chan->exten);
00952 if (ast_test_flag(&opts, OPT_PRIVACY) || ast_test_flag(&opts, OPT_SCREENING)) {
00953 char callerid[60];
00954 char *l = chan->cid.cid_num;
00955 if (!ast_strlen_zero(l)) {
00956 ast_shrink_phone_number(l);
00957 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
00958 if (option_verbose > 2)
00959 ast_verbose(VERBOSE_PREFIX_3 "Privacy DB is '%s', clid is '%s'\n",
00960 opt_args[OPT_ARG_PRIVACY], l);
00961 privdb_val = ast_privacy_check(opt_args[OPT_ARG_PRIVACY], l);
00962 }
00963 else {
00964 if (option_verbose > 2)
00965 ast_verbose(VERBOSE_PREFIX_3 "Privacy Screening, clid is '%s'\n", l);
00966 privdb_val = AST_PRIVACY_UNKNOWN;
00967 }
00968 } else {
00969 char *tnam, *tn2;
00970
00971 tnam = ast_strdupa(chan->name);
00972
00973 for(tn2 = tnam; *tn2; tn2++) {
00974 if( *tn2=='/')
00975 *tn2 = '=';
00976 }
00977 if (option_verbose > 2)
00978 ast_verbose(VERBOSE_PREFIX_3 "Privacy-- callerid is empty\n");
00979
00980 snprintf(callerid, sizeof(callerid), "NOCALLERID_%s%s", chan->exten, tnam);
00981 l = callerid;
00982 privdb_val = AST_PRIVACY_UNKNOWN;
00983 }
00984
00985 ast_copy_string(privcid,l,sizeof(privcid));
00986
00987 if( strncmp(privcid,"NOCALLERID",10) != 0 && ast_test_flag(&opts, OPT_SCREEN_NOCLID) ) {
00988 if (option_verbose > 2)
00989 ast_verbose( VERBOSE_PREFIX_3 "CallerID set (%s); N option set; Screening should be off\n", privcid);
00990 privdb_val = AST_PRIVACY_ALLOW;
00991 }
00992 else if(ast_test_flag(&opts, OPT_SCREEN_NOCLID) && strncmp(privcid,"NOCALLERID",10) == 0 ) {
00993 if (option_verbose > 2)
00994 ast_verbose( VERBOSE_PREFIX_3 "CallerID blank; N option set; Screening should happen; dbval is %d\n", privdb_val);
00995 }
00996
00997 if(privdb_val == AST_PRIVACY_DENY ) {
00998 ast_copy_string(status, "NOANSWER", sizeof(status));
00999 if (option_verbose > 2)
01000 ast_verbose( VERBOSE_PREFIX_3 "Privacy DB reports PRIVACY_DENY for this callerid. Dial reports unavailable\n");
01001 res=0;
01002 goto out;
01003 }
01004 else if(privdb_val == AST_PRIVACY_KILL ) {
01005 ast_copy_string(status, "DONTCALL", sizeof(status));
01006 if (ast_opt_priority_jumping || ast_test_flag(&opts, OPT_PRIORITY_JUMP)) {
01007 ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 201);
01008 }
01009 res = 0;
01010 goto out;
01011 }
01012 else if(privdb_val == AST_PRIVACY_TORTURE ) {
01013 ast_copy_string(status, "TORTURE", sizeof(status));
01014 if (ast_opt_priority_jumping || ast_test_flag(&opts, OPT_PRIORITY_JUMP)) {
01015 ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 301);
01016 }
01017 res = 0;
01018 goto out;
01019 }
01020 else if(privdb_val == AST_PRIVACY_UNKNOWN ) {
01021
01022
01023
01024
01025
01026 snprintf(privintro, sizeof(privintro), "%s/sounds/priv-callerintros", ast_config_AST_DATA_DIR);
01027 if (mkdir(privintro, 0755) && errno != EEXIST) {
01028 ast_log(LOG_WARNING, "privacy: can't create directory priv-callerintros: %s\n", strerror(errno));
01029 res = -1;
01030 goto out;
01031 }
01032
01033 snprintf(privintro,sizeof(privintro), "priv-callerintros/%s", privcid);
01034 if( ast_fileexists(privintro,NULL,NULL ) > 0 && strncmp(privcid,"NOCALLERID",10) != 0) {
01035
01036
01037
01038 }
01039 else {
01040 int duration;
01041
01042
01043
01044
01045
01046
01047
01048 ast_answer(chan);
01049 res = ast_play_and_record(chan, "priv-recordintro", privintro, 4, "gsm", &duration, 128, 2000, 0);
01050
01051
01052 if (res == -1) {
01053
01054 ast_filedelete(privintro, NULL);
01055 if( ast_fileexists(privintro,NULL,NULL ) > 0 )
01056 ast_log(LOG_NOTICE,"privacy: ast_filedelete didn't do its job on %s\n", privintro);
01057 else if (option_verbose > 2)
01058 ast_verbose( VERBOSE_PREFIX_3 "Successfully deleted %s intro file\n", privintro);
01059 goto out;
01060 }
01061 if( !ast_streamfile(chan, "vm-dialout", chan->language) )
01062 ast_waitstream(chan, "");
01063 }
01064 }
01065 }
01066
01067 if (continue_exec)
01068 *continue_exec = 0;
01069
01070
01071 if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP_ONCE"))) {
01072 outbound_group = ast_strdupa(outbound_group);
01073 pbx_builtin_setvar_helper(chan, "OUTBOUND_GROUP_ONCE", NULL);
01074 } else {
01075 outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP");
01076 }
01077
01078 ast_copy_flags(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID | OPT_CALLER_HANGUP | OPT_IGNORE_FORWARDING);
01079
01080 rest = args.peers;
01081 while ((cur = strsep(&rest, "&")) ) {
01082 struct dial_localuser *tmp;
01083
01084 char *number = cur;
01085 char *tech = strsep(&number, "/");
01086 if (!number) {
01087 ast_log(LOG_WARNING, "Dial argument takes format (technology/[device:]number1)\n");
01088 goto out;
01089 }
01090 if (!(tmp = ast_calloc(1, sizeof(*tmp))))
01091 goto out;
01092 if (opts.flags) {
01093 ast_copy_flags(tmp, &opts,
01094 OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
01095 OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
01096 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
01097 OPT_CALLEE_PARK | OPT_CALLER_PARK |
01098 OPT_RINGBACK | OPT_MUSICBACK | OPT_FORCECLID);
01099 ast_set2_flag(tmp, args.url, DIAL_NOFORWARDHTML);
01100 }
01101 ast_copy_string(numsubst, number, sizeof(numsubst));
01102
01103 tmp->chan = ast_request(tech, chan->nativeformats, numsubst, &cause);
01104 if (!tmp->chan) {
01105
01106 ast_log(LOG_WARNING, "Unable to create channel of type '%s' (cause %d - %s)\n", tech, cause, ast_cause2str(cause));
01107 HANDLE_CAUSE(cause, chan);
01108 if (!rest)
01109 chan->hangupcause = cause;
01110 free(tmp);
01111 continue;
01112 }
01113 pbx_builtin_setvar_helper(tmp->chan, "DIALEDPEERNUMBER", numsubst);
01114 if (!ast_strlen_zero(tmp->chan->call_forward)) {
01115 char tmpchan[256];
01116 char *stuff;
01117 char *tech;
01118 ast_copy_string(tmpchan, tmp->chan->call_forward, sizeof(tmpchan));
01119 if ((stuff = strchr(tmpchan, '/'))) {
01120 *stuff++ = '\0';
01121 tech = tmpchan;
01122 } else {
01123 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", tmp->chan->call_forward, tmp->chan->context);
01124 stuff = tmpchan;
01125 tech = "Local";
01126 }
01127 tmp->forwards++;
01128 if (tmp->forwards < AST_MAX_FORWARDS) {
01129 if (option_verbose > 2)
01130 ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n", chan->name, tech, stuff, tmp->chan->name);
01131 ast_hangup(tmp->chan);
01132
01133 if (ast_test_flag(&opts, OPT_IGNORE_FORWARDING)) {
01134 tmp->chan = NULL;
01135 cause = AST_CAUSE_BUSY;
01136 if (option_verbose > 2)
01137 ast_verbose(VERBOSE_PREFIX_3 "Forwarding %s to '%s/%s' prevented.\n", chan->name, tech, stuff);
01138 } else {
01139 tmp->chan = ast_request(tech, chan->nativeformats, stuff, &cause);
01140 }
01141 if (!tmp->chan)
01142 ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause);
01143 else
01144 ast_channel_inherit_variables(chan, tmp->chan);
01145 } else {
01146 if (option_verbose > 2)
01147 ast_verbose(VERBOSE_PREFIX_3 "Too many forwards from %s\n", tmp->chan->name);
01148 ast_hangup(tmp->chan);
01149 tmp->chan = NULL;
01150 cause = AST_CAUSE_CONGESTION;
01151 }
01152 if (!tmp->chan) {
01153 HANDLE_CAUSE(cause, chan);
01154 free(tmp);
01155 continue;
01156 }
01157 }
01158
01159
01160 ast_rtp_make_compatible(tmp->chan, chan, !outgoing && !rest);
01161
01162
01163 ast_channel_inherit_variables(chan, tmp->chan);
01164
01165 tmp->chan->appl = "AppDial";
01166 tmp->chan->data = "(Outgoing Line)";
01167 tmp->chan->whentohangup = 0;
01168
01169 if (tmp->chan->cid.cid_num)
01170 free(tmp->chan->cid.cid_num);
01171 tmp->chan->cid.cid_num = ast_strdup(chan->cid.cid_num);
01172
01173 if (tmp->chan->cid.cid_name)
01174 free(tmp->chan->cid.cid_name);
01175 tmp->chan->cid.cid_name = ast_strdup(chan->cid.cid_name);
01176
01177 if (tmp->chan->cid.cid_ani)
01178 free(tmp->chan->cid.cid_ani);
01179 tmp->chan->cid.cid_ani = ast_strdup(chan->cid.cid_ani);
01180
01181
01182 ast_string_field_set(tmp->chan, language, chan->language);
01183 ast_string_field_set(tmp->chan, accountcode, chan->accountcode);
01184 tmp->chan->cdrflags = chan->cdrflags;
01185 if (ast_strlen_zero(tmp->chan->musicclass))
01186 ast_string_field_set(tmp->chan, musicclass, chan->musicclass);
01187
01188 tmp->chan->cid.cid_rdnis = ast_strdup(chan->cid.cid_rdnis);
01189
01190 tmp->chan->cid.cid_pres = chan->cid.cid_pres;
01191
01192 tmp->chan->cid.cid_ton = chan->cid.cid_ton;
01193
01194 tmp->chan->cid.cid_tns = chan->cid.cid_tns;
01195
01196 tmp->chan->adsicpe = chan->adsicpe;
01197
01198 tmp->chan->transfercapability = chan->transfercapability;
01199
01200
01201 if (outbound_group)
01202 ast_app_group_set_channel(tmp->chan, outbound_group);
01203
01204
01205 if (!ast_strlen_zero(chan->macrocontext))
01206 ast_copy_string(tmp->chan->dialcontext, chan->macrocontext, sizeof(tmp->chan->dialcontext));
01207 else
01208 ast_copy_string(tmp->chan->dialcontext, chan->context, sizeof(tmp->chan->dialcontext));
01209 if (!ast_strlen_zero(chan->macroexten))
01210 ast_copy_string(tmp->chan->exten, chan->macroexten, sizeof(tmp->chan->exten));
01211 else
01212 ast_copy_string(tmp->chan->exten, chan->exten, sizeof(tmp->chan->exten));
01213
01214
01215 res = ast_call(tmp->chan, numsubst, 0);
01216
01217
01218 if (chan->cdr)
01219 ast_cdr_setdestchan(chan->cdr, tmp->chan->name);
01220
01221
01222 if (res) {
01223
01224 if (option_debug)
01225 ast_log(LOG_DEBUG, "ast call on peer returned %d\n", res);
01226 if (option_verbose > 2)
01227 ast_verbose(VERBOSE_PREFIX_3 "Couldn't call %s\n", numsubst);
01228 ast_hangup(tmp->chan);
01229 tmp->chan = NULL;
01230 free(tmp);
01231 continue;
01232 } else {
01233 senddialevent(chan, tmp->chan);
01234 if (option_verbose > 2)
01235 ast_verbose(VERBOSE_PREFIX_3 "Called %s\n", numsubst);
01236 if (!ast_test_flag(peerflags, OPT_ORIGINAL_CLID))
01237 ast_set_callerid(tmp->chan, S_OR(chan->macroexten, chan->exten), get_cid_name(cidname, sizeof(cidname), chan), NULL);
01238 }
01239
01240
01241
01242 ast_set_flag(tmp, DIAL_STILLGOING);
01243 tmp->next = outgoing;
01244 outgoing = tmp;
01245
01246 if (outgoing->chan->_state == AST_STATE_UP)
01247 break;
01248 }
01249
01250 if (ast_strlen_zero(args.timeout)) {
01251 to = -1;
01252 } else {
01253 to = atoi(args.timeout);
01254 if (to > 0)
01255 to *= 1000;
01256 else
01257 ast_log(LOG_WARNING, "Invalid timeout specified: '%s'\n", args.timeout);
01258 }
01259
01260 if (!outgoing) {
01261 strcpy(status, "CHANUNAVAIL");
01262 } else {
01263
01264 strcpy(status, "NOANSWER");
01265 if (ast_test_flag(outgoing, OPT_MUSICBACK)) {
01266 moh = 1;
01267 if (!ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
01268 char *original_moh = ast_strdupa(chan->musicclass);
01269 ast_string_field_set(chan, musicclass, opt_args[OPT_ARG_MUSICBACK]);
01270 ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
01271 ast_string_field_set(chan, musicclass, original_moh);
01272 } else {
01273 ast_moh_start(chan, NULL, NULL);
01274 }
01275 ast_indicate(chan, AST_CONTROL_PROGRESS);
01276 } else if (ast_test_flag(outgoing, OPT_RINGBACK)) {
01277 ast_indicate(chan, AST_CONTROL_RINGING);
01278 sentringing++;
01279 }
01280 }
01281
01282 time(&start_time);
01283 peer = wait_for_answer(chan, outgoing, &to, peerflags, &sentringing, status, sizeof(status), numbusy, numnochan, numcongestion, ast_test_flag(&opts, OPT_PRIORITY_JUMP), &result);
01284
01285 if (!peer) {
01286 if (result) {
01287 res = result;
01288 } else if (to) {
01289 res = -1;
01290 } else {
01291 res = 0;
01292 }
01293
01294 } else {
01295 const char *number;
01296 time_t end_time, answer_time = time(NULL);
01297
01298 strcpy(status, "ANSWER");
01299
01300
01301
01302 hanguptree(outgoing, peer);
01303 outgoing = NULL;
01304
01305 if (chan->cdr)
01306 ast_cdr_setdestchan(chan->cdr, peer->name);
01307 if (peer->name)
01308 pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", peer->name);
01309
01310 number = pbx_builtin_getvar_helper(peer, "DIALEDPEERNUMBER");
01311 if (!number)
01312 number = numsubst;
01313 pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", number);
01314 if (!ast_strlen_zero(args.url) && ast_channel_supports_html(peer) ) {
01315 if (option_debug)
01316 ast_log(LOG_DEBUG, "app_dial: sendurl=%s.\n", args.url);
01317 ast_channel_sendurl( peer, args.url );
01318 }
01319 if ( (ast_test_flag(&opts, OPT_PRIVACY) || ast_test_flag(&opts, OPT_SCREENING)) && privdb_val == AST_PRIVACY_UNKNOWN) {
01320 int res2;
01321 int loopcount = 0;
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331 if (ast_test_flag(&opts, OPT_MUSICBACK) && !ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
01332 char *original_moh = ast_strdupa(chan->musicclass);
01333 ast_indicate(chan, -1);
01334 ast_string_field_set(chan, musicclass, opt_args[OPT_ARG_MUSICBACK]);
01335 ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
01336 ast_string_field_set(chan, musicclass, original_moh);
01337 } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
01338 ast_indicate(chan, AST_CONTROL_RINGING);
01339 sentringing++;
01340 }
01341
01342
01343 res2 = ast_autoservice_start(chan);
01344
01345 for (loopcount = 0; loopcount < 3; loopcount++) {
01346 if (res2 && loopcount == 0)
01347 break;
01348 if (!res2)
01349 res2 = ast_play_and_wait(peer,"priv-callpending");
01350 if (!valid_priv_reply(&opts, res2))
01351 res2 = 0;
01352
01353
01354
01355 if (!res2)
01356 res2 = ast_play_and_wait(peer,privintro);
01357 if (!valid_priv_reply(&opts, res2))
01358 res2 = 0;
01359
01360 if( !res2 ) {
01361
01362 if( ast_test_flag(&opts, OPT_PRIVACY) )
01363 res2 = ast_play_and_wait(peer,"priv-callee-options");
01364 if( ast_test_flag(&opts, OPT_SCREENING) )
01365 res2 = ast_play_and_wait(peer,"screen-callee-options");
01366 }
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383 if (valid_priv_reply(&opts, res2))
01384 break;
01385
01386 res2 = ast_play_and_wait(peer, "vm-sorry");
01387 }
01388
01389 if (ast_test_flag(&opts, OPT_MUSICBACK)) {
01390 ast_moh_stop(chan);
01391 } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
01392 ast_indicate(chan, -1);
01393 sentringing=0;
01394 }
01395 ast_autoservice_stop(chan);
01396
01397 switch (res2) {
01398 case '1':
01399 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
01400 if (option_verbose > 2)
01401 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to ALLOW\n",
01402 opt_args[OPT_ARG_PRIVACY], privcid);
01403 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_ALLOW);
01404 }
01405 break;
01406 case '2':
01407 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
01408 if (option_verbose > 2)
01409 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to DENY\n",
01410 opt_args[OPT_ARG_PRIVACY], privcid);
01411 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_DENY);
01412 }
01413 ast_copy_string(status, "NOANSWER", sizeof(status));
01414 ast_hangup(peer);
01415 res=0;
01416 goto out;
01417 case '3':
01418 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
01419 if (option_verbose > 2)
01420 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to TORTURE\n",
01421 opt_args[OPT_ARG_PRIVACY], privcid);
01422 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_TORTURE);
01423 }
01424 ast_copy_string(status, "TORTURE", sizeof(status));
01425
01426 res = 0;
01427 ast_hangup(peer);
01428 goto out;
01429 case '4':
01430 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
01431 if (option_verbose > 2)
01432 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to KILL\n",
01433 opt_args[OPT_ARG_PRIVACY], privcid);
01434 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_KILL);
01435 }
01436
01437 ast_copy_string(status, "DONTCALL", sizeof(status));
01438 res = 0;
01439 ast_hangup(peer);
01440 goto out;
01441 case '5':
01442 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
01443 if (option_verbose > 2)
01444 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to ALLOW\n",
01445 opt_args[OPT_ARG_PRIVACY], privcid);
01446 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_ALLOW);
01447 ast_hangup(peer);
01448 res=0;
01449 goto out;
01450 }
01451 default:
01452
01453
01454
01455
01456 ast_log(LOG_NOTICE, "privacy: no valid response from the callee. Sending the caller to voicemail, the callee isn't responding\n");
01457 ast_hangup(peer);
01458 res=0;
01459 goto out;
01460 }
01461
01462
01463
01464
01465
01466
01467
01468 if( strncmp(privcid,"NOCALLERID",10) == 0 || ast_test_flag(&opts, OPT_SCREEN_NOINTRO) ) {
01469 ast_filedelete(privintro, NULL);
01470 if( ast_fileexists(privintro, NULL, NULL ) > 0 )
01471 ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", privintro);
01472 else if (option_verbose > 2)
01473 ast_verbose(VERBOSE_PREFIX_3 "Successfully deleted %s intro file\n", privintro);
01474 }
01475 }
01476 if (!ast_test_flag(&opts, OPT_ANNOUNCE) || ast_strlen_zero(opt_args[OPT_ARG_ANNOUNCE])) {
01477 res = 0;
01478 } else {
01479 int digit = 0;
01480
01481 res = ast_autoservice_start(chan);
01482
01483 if (!res)
01484 res = ast_streamfile(peer, opt_args[OPT_ARG_ANNOUNCE], peer->language);
01485 if (!res) {
01486 digit = ast_waitstream(peer, AST_DIGIT_ANY);
01487 }
01488
01489 res = ast_autoservice_stop(chan);
01490 if (digit > 0 && !res)
01491 res = ast_senddigit(chan, digit);
01492 else
01493 res = digit;
01494
01495 }
01496
01497 if (chan && peer && ast_test_flag(&opts, OPT_GOTO) && !ast_strlen_zero(opt_args[OPT_ARG_GOTO])) {
01498 replace_macro_delimiter(opt_args[OPT_ARG_GOTO]);
01499 ast_parseable_goto(chan, opt_args[OPT_ARG_GOTO]);
01500 ast_parseable_goto(peer, opt_args[OPT_ARG_GOTO]);
01501 peer->priority++;
01502 ast_pbx_start(peer);
01503 hanguptree(outgoing, NULL);
01504 if (continue_exec)
01505 *continue_exec = 1;
01506 res = 0;
01507 goto done;
01508 }
01509
01510 if (ast_test_flag(&opts, OPT_CALLEE_MACRO) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_MACRO])) {
01511 struct ast_app *theapp;
01512 const char *macro_result;
01513
01514 res = ast_autoservice_start(chan);
01515 if (res) {
01516 ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
01517 res = -1;
01518 }
01519
01520 theapp = pbx_findapp("Macro");
01521
01522 if (theapp && !res) {
01523 replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_MACRO]);
01524 res = pbx_exec(peer, theapp, opt_args[OPT_ARG_CALLEE_MACRO]);
01525 ast_log(LOG_DEBUG, "Macro exited with status %d\n", res);
01526 res = 0;
01527 } else {
01528 ast_log(LOG_ERROR, "Could not find application Macro\n");
01529 res = -1;
01530 }
01531
01532 if (ast_autoservice_stop(chan) < 0) {
01533 ast_log(LOG_ERROR, "Could not stop autoservice on calling channel\n");
01534 res = -1;
01535 }
01536
01537 if (!res && (macro_result = pbx_builtin_getvar_helper(peer, "MACRO_RESULT"))) {
01538 char *macro_transfer_dest;
01539
01540 if (!strcasecmp(macro_result, "BUSY")) {
01541 ast_copy_string(status, macro_result, sizeof(status));
01542 if (ast_opt_priority_jumping || ast_test_flag(&opts, OPT_PRIORITY_JUMP)) {
01543 if (!ast_goto_if_exists(chan, NULL, NULL, chan->priority + 101)) {
01544 ast_set_flag(peerflags, OPT_GO_ON);
01545 }
01546 } else
01547 ast_set_flag(peerflags, OPT_GO_ON);
01548 res = -1;
01549 } else if (!strcasecmp(macro_result, "CONGESTION") || !strcasecmp(macro_result, "CHANUNAVAIL")) {
01550 ast_copy_string(status, macro_result, sizeof(status));
01551 ast_set_flag(peerflags, OPT_GO_ON);
01552 res = -1;
01553 } else if (!strcasecmp(macro_result, "CONTINUE")) {
01554
01555
01556
01557
01558 ast_set_flag(peerflags, OPT_GO_ON);
01559 res = -1;
01560 } else if (!strcasecmp(macro_result, "ABORT")) {
01561
01562 res = -1;
01563 } else if (!strncasecmp(macro_result, "GOTO:", 5) && (macro_transfer_dest = ast_strdupa(macro_result + 5))) {
01564 res = -1;
01565
01566 if (strchr(macro_transfer_dest, '^')) {
01567 replace_macro_delimiter(macro_transfer_dest);
01568 if (!ast_parseable_goto(chan, macro_transfer_dest))
01569 ast_set_flag(peerflags, OPT_GO_ON);
01570
01571 }
01572 }
01573 }
01574 }
01575
01576 if (!res) {
01577 if (calldurationlimit > 0) {
01578 peer->whentohangup = time(NULL) + calldurationlimit;
01579 }
01580 if (!ast_strlen_zero(dtmfcalled)) {
01581 if (option_verbose > 2)
01582 ast_verbose(VERBOSE_PREFIX_3 "Sending DTMF '%s' to the called party.\n", dtmfcalled);
01583 res = ast_dtmf_stream(peer,chan,dtmfcalled,250);
01584 }
01585 if (!ast_strlen_zero(dtmfcalling)) {
01586 if (option_verbose > 2)
01587 ast_verbose(VERBOSE_PREFIX_3 "Sending DTMF '%s' to the calling party.\n", dtmfcalling);
01588 res = ast_dtmf_stream(chan,peer,dtmfcalling,250);
01589 }
01590 }
01591
01592 if (!res) {
01593 struct ast_bridge_config config;
01594
01595 memset(&config,0,sizeof(struct ast_bridge_config));
01596 if (play_to_caller)
01597 ast_set_flag(&(config.features_caller), AST_FEATURE_PLAY_WARNING);
01598 if (play_to_callee)
01599 ast_set_flag(&(config.features_callee), AST_FEATURE_PLAY_WARNING);
01600 if (ast_test_flag(peerflags, OPT_CALLEE_TRANSFER))
01601 ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
01602 if (ast_test_flag(peerflags, OPT_CALLER_TRANSFER))
01603 ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
01604 if (ast_test_flag(peerflags, OPT_CALLEE_HANGUP))
01605 ast_set_flag(&(config.features_callee), AST_FEATURE_DISCONNECT);
01606 if (ast_test_flag(peerflags, OPT_CALLER_HANGUP))
01607 ast_set_flag(&(config.features_caller), AST_FEATURE_DISCONNECT);
01608 if (ast_test_flag(peerflags, OPT_CALLEE_MONITOR))
01609 ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMON);
01610 if (ast_test_flag(peerflags, OPT_CALLER_MONITOR))
01611 ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMON);
01612 if (ast_test_flag(peerflags, OPT_CALLEE_PARK))
01613 ast_set_flag(&(config.features_callee), AST_FEATURE_PARKCALL);
01614 if (ast_test_flag(peerflags, OPT_CALLER_PARK))
01615 ast_set_flag(&(config.features_caller), AST_FEATURE_PARKCALL);
01616
01617 config.timelimit = timelimit;
01618 config.play_warning = play_warning;
01619 config.warning_freq = warning_freq;
01620 config.warning_sound = warning_sound;
01621 config.end_sound = end_sound;
01622 config.start_sound = start_sound;
01623 if (moh) {
01624 moh = 0;
01625 ast_moh_stop(chan);
01626 } else if (sentringing) {
01627 sentringing = 0;
01628 ast_indicate(chan, -1);
01629 }
01630
01631 ast_deactivate_generator(chan);
01632
01633 res = ast_channel_make_compatible(chan, peer);
01634 if (res < 0) {
01635 ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", chan->name, peer->name);
01636 ast_hangup(peer);
01637 res = -1;
01638 goto done;
01639 }
01640 if (opermode && (!strncmp(chan->name,"Zap",3)) &&
01641 (!strncmp(peer->name,"Zap",3)))
01642 {
01643 struct oprmode oprmode;
01644
01645 oprmode.peer = peer;
01646 oprmode.mode = opermode;
01647
01648 ast_channel_setoption(chan,
01649 AST_OPTION_OPRMODE,&oprmode,sizeof(struct oprmode),0);
01650 }
01651 res = ast_bridge_call(chan,peer,&config);
01652 time(&end_time);
01653 {
01654 char toast[80];
01655 snprintf(toast, sizeof(toast), "%ld", (long)(end_time - answer_time));
01656 pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", toast);
01657 }
01658 } else {
01659 time(&end_time);
01660 res = -1;
01661 }
01662 {
01663 char toast[80];
01664 snprintf(toast, sizeof(toast), "%ld", (long)(end_time - start_time));
01665 pbx_builtin_setvar_helper(chan, "DIALEDTIME", toast);
01666 }
01667
01668 if (res != AST_PBX_NO_HANGUP_PEER) {
01669 if (!chan->_softhangup)
01670 chan->hangupcause = peer->hangupcause;
01671 ast_hangup(peer);
01672 }
01673 }
01674 out:
01675 if (moh) {
01676 moh = 0;
01677 ast_moh_stop(chan);
01678 } else if (sentringing) {
01679 sentringing = 0;
01680 ast_indicate(chan, -1);
01681 }
01682 ast_rtp_early_bridge(chan, NULL);
01683 hanguptree(outgoing, NULL);
01684 pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
01685 if (option_debug)
01686 ast_log(LOG_DEBUG, "Exiting with DIALSTATUS=%s.\n", status);
01687
01688 if ((ast_test_flag(peerflags, OPT_GO_ON)) && (!chan->_softhangup) && (res != AST_PBX_KEEPALIVE)) {
01689 if (calldurationlimit)
01690 chan->whentohangup = 0;
01691 res = 0;
01692 }
01693
01694 done:
01695 ast_module_user_remove(u);
01696 return res;
01697 }
01698
01699 static int dial_exec(struct ast_channel *chan, void *data)
01700 {
01701 struct ast_flags peerflags;
01702
01703 memset(&peerflags, 0, sizeof(peerflags));
01704
01705 return dial_exec_full(chan, data, &peerflags, NULL);
01706 }
01707
01708 static int retrydial_exec(struct ast_channel *chan, void *data)
01709 {
01710 char *announce = NULL, *dialdata = NULL;
01711 const char *context = NULL;
01712 int sleep = 0, loops = 0, res = -1;
01713 struct ast_module_user *u;
01714 struct ast_flags peerflags;
01715
01716 if (ast_strlen_zero(data)) {
01717 ast_log(LOG_WARNING, "RetryDial requires an argument!\n");
01718 return -1;
01719 }
01720
01721 u = ast_module_user_add(chan);
01722
01723 announce = ast_strdupa(data);
01724
01725 memset(&peerflags, 0, sizeof(peerflags));
01726
01727 if ((dialdata = strchr(announce, '|'))) {
01728 *dialdata++ = '\0';
01729 if (sscanf(dialdata, "%d", &sleep) == 1) {
01730 sleep *= 1000;
01731 } else {
01732 ast_log(LOG_ERROR, "%s requires the numerical argument <sleep>\n",rapp);
01733 goto done;
01734 }
01735 if ((dialdata = strchr(dialdata, '|'))) {
01736 *dialdata++ = '\0';
01737 if (sscanf(dialdata, "%d", &loops) != 1) {
01738 ast_log(LOG_ERROR, "%s requires the numerical argument <loops>\n",rapp);
01739 goto done;
01740 }
01741 }
01742 }
01743
01744 if ((dialdata = strchr(dialdata, '|'))) {
01745 *dialdata++ = '\0';
01746 } else {
01747 ast_log(LOG_ERROR, "%s requires more arguments\n",rapp);
01748 goto done;
01749 }
01750
01751 if (sleep < 1000)
01752 sleep = 10000;
01753
01754 if (!loops)
01755 loops = -1;
01756
01757 context = pbx_builtin_getvar_helper(chan, "EXITCONTEXT");
01758
01759 res = 0;
01760 while (loops) {
01761 int continue_exec;
01762
01763 chan->data = "Retrying";
01764 if (ast_test_flag(chan, AST_FLAG_MOH))
01765 ast_moh_stop(chan);
01766
01767 res = dial_exec_full(chan, dialdata, &peerflags, &continue_exec);
01768 if (continue_exec)
01769 break;
01770
01771 if (res == 0) {
01772 if (ast_test_flag(&peerflags, OPT_DTMF_EXIT)) {
01773 if (!ast_strlen_zero(announce)) {
01774 if (ast_fileexists(announce, NULL, chan->language) > 0) {
01775 if(!(res = ast_streamfile(chan, announce, chan->language)))
01776 ast_waitstream(chan, AST_DIGIT_ANY);
01777 } else
01778 ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", announce);
01779 }
01780 if (!res && sleep) {
01781 if (!ast_test_flag(chan, AST_FLAG_MOH))
01782 ast_moh_start(chan, NULL, NULL);
01783 res = ast_waitfordigit(chan, sleep);
01784 }
01785 } else {
01786 if (!ast_strlen_zero(announce)) {
01787 if (ast_fileexists(announce, NULL, chan->language) > 0) {
01788 if (!(res = ast_streamfile(chan, announce, chan->language)))
01789 res = ast_waitstream(chan, "");
01790 } else
01791 ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", announce);
01792 }
01793 if (sleep) {
01794 if (!ast_test_flag(chan, AST_FLAG_MOH))
01795 ast_moh_start(chan, NULL, NULL);
01796 if (!res)
01797 res = ast_waitfordigit(chan, sleep);
01798 }
01799 }
01800 }
01801
01802 if (res < 0)
01803 break;
01804 else if (res > 0) {
01805 if (onedigit_goto(chan, context, (char) res, 1)) {
01806 res = 0;
01807 break;
01808 }
01809 }
01810 loops--;
01811 }
01812 if (loops == 0)
01813 res = 0;
01814 else if (res == 1)
01815 res = 0;
01816
01817 if (ast_test_flag(chan, AST_FLAG_MOH))
01818 ast_moh_stop(chan);
01819 done:
01820 ast_module_user_remove(u);
01821 return res;
01822 }
01823
01824 static int unload_module(void)
01825 {
01826 int res;
01827
01828 res = ast_unregister_application(app);
01829 res |= ast_unregister_application(rapp);
01830
01831 ast_module_user_hangup_all();
01832
01833 return res;
01834 }
01835
01836 static int load_module(void)
01837 {
01838 int res;
01839
01840 res = ast_register_application(app, dial_exec, synopsis, descrip);
01841 res |= ast_register_application(rapp, retrydial_exec, rsynopsis, rdescrip);
01842
01843 return res;
01844 }
01845
01846 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Dialing Application");