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$")
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 strcpy(status, "CANCEL");
00700 if (f)
00701 ast_frfree(f);
00702 return NULL;
00703 }
00704
00705 if (f && (f->frametype == AST_FRAME_DTMF)) {
00706 if (ast_test_flag(peerflags, OPT_DTMF_EXIT)) {
00707 const char *context = pbx_builtin_getvar_helper(in, "EXITCONTEXT");
00708 if (onedigit_goto(in, context, (char) f->subclass, 1)) {
00709 if (option_verbose > 2)
00710 ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
00711 *to=0;
00712 *result = f->subclass;
00713 strcpy(status, "CANCEL");
00714 ast_frfree(f);
00715 return NULL;
00716 }
00717 }
00718
00719 if (ast_test_flag(peerflags, OPT_CALLER_HANGUP) &&
00720 (f->subclass == '*')) {
00721 if (option_verbose > 2)
00722 ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
00723 *to=0;
00724 strcpy(status, "CANCEL");
00725 ast_frfree(f);
00726 return NULL;
00727 }
00728 }
00729
00730
00731 if (single && f && (f->frametype == AST_FRAME_HTML) && !ast_test_flag(outgoing, DIAL_NOFORWARDHTML))
00732 if(ast_channel_sendhtml(outgoing->chan, f->subclass, f->data, f->datalen) == -1)
00733 ast_log(LOG_WARNING, "Unable to send URL\n");
00734
00735
00736 if (single && ((f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_DTMF_BEGIN) || (f->frametype == AST_FRAME_DTMF_END))) {
00737 if (ast_write(outgoing->chan, f))
00738 ast_log(LOG_WARNING, "Unable to forward voice or dtmf\n");
00739 }
00740 if (single && (f->frametype == AST_FRAME_CONTROL) &&
00741 ((f->subclass == AST_CONTROL_HOLD) ||
00742 (f->subclass == AST_CONTROL_UNHOLD) ||
00743 (f->subclass == AST_CONTROL_VIDUPDATE))) {
00744 if (option_verbose > 2)
00745 ast_verbose(VERBOSE_PREFIX_3 "%s requested special control %d, passing it to %s\n", in->name, f->subclass, outgoing->chan->name);
00746 ast_indicate_data(outgoing->chan, f->subclass, f->data, f->datalen);
00747 }
00748 ast_frfree(f);
00749 }
00750 if (!*to && (option_verbose > 2))
00751 ast_verbose(VERBOSE_PREFIX_3 "Nobody picked up in %d ms\n", orig);
00752 }
00753
00754 return peer;
00755 }
00756
00757 static void replace_macro_delimiter(char *s)
00758 {
00759 for (; *s; s++)
00760 if (*s == '^')
00761 *s = '|';
00762 }
00763
00764
00765
00766 static int valid_priv_reply(struct ast_flags *opts, int res)
00767 {
00768 if (res < '1')
00769 return 0;
00770 if (ast_test_flag(opts, OPT_PRIVACY) && res <= '5')
00771 return 1;
00772 if (ast_test_flag(opts, OPT_SCREENING) && res <= '4')
00773 return 1;
00774 return 0;
00775 }
00776
00777 static int dial_exec_full(struct ast_channel *chan, void *data, struct ast_flags *peerflags, int *continue_exec)
00778 {
00779 int res = -1;
00780 struct ast_module_user *u;
00781 char *rest, *cur;
00782 struct dial_localuser *outgoing = NULL;
00783 struct ast_channel *peer;
00784 int to;
00785 int numbusy = 0;
00786 int numcongestion = 0;
00787 int numnochan = 0;
00788 int cause;
00789 char numsubst[AST_MAX_EXTENSION];
00790 char cidname[AST_MAX_EXTENSION];
00791 int privdb_val = 0;
00792 unsigned int calldurationlimit = 0;
00793 long timelimit = 0;
00794 long play_warning = 0;
00795 long warning_freq = 0;
00796 const char *warning_sound = NULL;
00797 const char *end_sound = NULL;
00798 const char *start_sound = NULL;
00799 char *dtmfcalled = NULL, *dtmfcalling = NULL;
00800 char status[256] = "INVALIDARGS";
00801 int play_to_caller = 0, play_to_callee = 0;
00802 int sentringing = 0, moh = 0;
00803 const char *outbound_group = NULL;
00804 int result = 0;
00805 time_t start_time;
00806 char privintro[1024];
00807 char privcid[256];
00808 char *parse;
00809 int opermode = 0;
00810 AST_DECLARE_APP_ARGS(args,
00811 AST_APP_ARG(peers);
00812 AST_APP_ARG(timeout);
00813 AST_APP_ARG(options);
00814 AST_APP_ARG(url);
00815 );
00816 struct ast_flags opts = { 0, };
00817 char *opt_args[OPT_ARG_ARRAY_SIZE];
00818
00819 if (ast_strlen_zero(data)) {
00820 ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
00821 pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
00822 return -1;
00823 }
00824
00825 u = ast_module_user_add(chan);
00826
00827 parse = ast_strdupa(data);
00828
00829 AST_STANDARD_APP_ARGS(args, parse);
00830
00831 if (!ast_strlen_zero(args.options) &&
00832 ast_app_parse_options(dial_exec_options, &opts, opt_args, args.options)) {
00833 pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
00834 goto done;
00835 }
00836
00837 if (ast_strlen_zero(args.peers)) {
00838 ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
00839 pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
00840 goto done;
00841 }
00842
00843 if (ast_test_flag(&opts, OPT_OPERMODE)) {
00844 if (ast_strlen_zero(opt_args[OPT_ARG_OPERMODE]))
00845 opermode = 1;
00846 else opermode = atoi(opt_args[OPT_ARG_OPERMODE]);
00847 if (option_verbose > 2)
00848 ast_verbose(VERBOSE_PREFIX_3 "Setting operator services mode to %d.\n", opermode);
00849 }
00850
00851 if (ast_test_flag(&opts, OPT_DURATION_STOP) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_STOP])) {
00852 calldurationlimit = atoi(opt_args[OPT_ARG_DURATION_STOP]);
00853 if (!calldurationlimit) {
00854 ast_log(LOG_WARNING, "Dial does not accept S(%s), hanging up.\n", opt_args[OPT_ARG_DURATION_STOP]);
00855 pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
00856 goto done;
00857 }
00858 if (option_verbose > 2)
00859 ast_verbose(VERBOSE_PREFIX_3 "Setting call duration limit to %d seconds.\n", calldurationlimit);
00860 }
00861
00862 if (ast_test_flag(&opts, OPT_SENDDTMF) && !ast_strlen_zero(opt_args[OPT_ARG_SENDDTMF])) {
00863 dtmfcalling = opt_args[OPT_ARG_SENDDTMF];
00864 dtmfcalled = strsep(&dtmfcalling, ":");
00865 }
00866
00867 if (ast_test_flag(&opts, OPT_DURATION_LIMIT) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_LIMIT])) {
00868 char *limit_str, *warning_str, *warnfreq_str;
00869 const char *var;
00870
00871 warnfreq_str = opt_args[OPT_ARG_DURATION_LIMIT];
00872 limit_str = strsep(&warnfreq_str, ":");
00873 warning_str = strsep(&warnfreq_str, ":");
00874
00875 timelimit = atol(limit_str);
00876 if (warning_str)
00877 play_warning = atol(warning_str);
00878 if (warnfreq_str)
00879 warning_freq = atol(warnfreq_str);
00880
00881 if (!timelimit) {
00882 ast_log(LOG_WARNING, "Dial does not accept L(%s), hanging up.\n", limit_str);
00883 goto done;
00884 } else if (play_warning > timelimit) {
00885
00886
00887
00888
00889
00890
00891 if (!warning_freq) {
00892 play_warning = 0;
00893 } else {
00894
00895 while (play_warning > timelimit)
00896 play_warning -= warning_freq;
00897 if (play_warning < 1)
00898 play_warning = warning_freq = 0;
00899 }
00900 }
00901
00902 var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLER");
00903 play_to_caller = var ? ast_true(var) : 1;
00904
00905 var = pbx_builtin_getvar_helper(chan,"LIMIT_PLAYAUDIO_CALLEE");
00906 play_to_callee = var ? ast_true(var) : 0;
00907
00908 if (!play_to_caller && !play_to_callee)
00909 play_to_caller = 1;
00910
00911 var = pbx_builtin_getvar_helper(chan,"LIMIT_WARNING_FILE");
00912 warning_sound = S_OR(var, "timeleft");
00913
00914 var = pbx_builtin_getvar_helper(chan,"LIMIT_TIMEOUT_FILE");
00915 end_sound = S_OR(var, NULL);
00916
00917 var = pbx_builtin_getvar_helper(chan,"LIMIT_CONNECT_FILE");
00918 start_sound = S_OR(var, NULL);
00919
00920
00921 calldurationlimit = 0;
00922
00923 if (!play_warning && !start_sound && !end_sound && timelimit) {
00924 calldurationlimit = timelimit / 1000;
00925 if (option_verbose > 2)
00926 ast_verbose(VERBOSE_PREFIX_3 "Setting call duration limit to %d seconds.\n", calldurationlimit);
00927 timelimit = play_to_caller = play_to_callee = play_warning = warning_freq = 0;
00928 } else if (option_verbose > 2) {
00929 ast_verbose(VERBOSE_PREFIX_3 "Limit Data for this call:\n");
00930 ast_verbose(VERBOSE_PREFIX_4 "timelimit = %ld\n", timelimit);
00931 ast_verbose(VERBOSE_PREFIX_4 "play_warning = %ld\n", play_warning);
00932 ast_verbose(VERBOSE_PREFIX_4 "play_to_caller = %s\n", play_to_caller ? "yes" : "no");
00933 ast_verbose(VERBOSE_PREFIX_4 "play_to_callee = %s\n", play_to_callee ? "yes" : "no");
00934 ast_verbose(VERBOSE_PREFIX_4 "warning_freq = %ld\n", warning_freq);
00935 ast_verbose(VERBOSE_PREFIX_4 "start_sound = %s\n", start_sound);
00936 ast_verbose(VERBOSE_PREFIX_4 "warning_sound = %s\n", warning_sound);
00937 ast_verbose(VERBOSE_PREFIX_4 "end_sound = %s\n", end_sound);
00938 }
00939 }
00940
00941 if (ast_test_flag(&opts, OPT_RESETCDR) && chan->cdr)
00942 ast_cdr_reset(chan->cdr, NULL);
00943 if (ast_test_flag(&opts, OPT_PRIVACY) && ast_strlen_zero(opt_args[OPT_ARG_PRIVACY]))
00944 opt_args[OPT_ARG_PRIVACY] = ast_strdupa(chan->exten);
00945 if (ast_test_flag(&opts, OPT_PRIVACY) || ast_test_flag(&opts, OPT_SCREENING)) {
00946 char callerid[60];
00947 char *l = chan->cid.cid_num;
00948 if (!ast_strlen_zero(l)) {
00949 ast_shrink_phone_number(l);
00950 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
00951 if (option_verbose > 2)
00952 ast_verbose(VERBOSE_PREFIX_3 "Privacy DB is '%s', clid is '%s'\n",
00953 opt_args[OPT_ARG_PRIVACY], l);
00954 privdb_val = ast_privacy_check(opt_args[OPT_ARG_PRIVACY], l);
00955 }
00956 else {
00957 if (option_verbose > 2)
00958 ast_verbose(VERBOSE_PREFIX_3 "Privacy Screening, clid is '%s'\n", l);
00959 privdb_val = AST_PRIVACY_UNKNOWN;
00960 }
00961 } else {
00962 char *tnam, *tn2;
00963
00964 tnam = ast_strdupa(chan->name);
00965
00966 for(tn2 = tnam; *tn2; tn2++) {
00967 if( *tn2=='/')
00968 *tn2 = '=';
00969 }
00970 if (option_verbose > 2)
00971 ast_verbose(VERBOSE_PREFIX_3 "Privacy-- callerid is empty\n");
00972
00973 snprintf(callerid, sizeof(callerid), "NOCALLERID_%s%s", chan->exten, tnam);
00974 l = callerid;
00975 privdb_val = AST_PRIVACY_UNKNOWN;
00976 }
00977
00978 ast_copy_string(privcid,l,sizeof(privcid));
00979
00980 if( strncmp(privcid,"NOCALLERID",10) != 0 && ast_test_flag(&opts, OPT_SCREEN_NOCLID) ) {
00981 if (option_verbose > 2)
00982 ast_verbose( VERBOSE_PREFIX_3 "CallerID set (%s); N option set; Screening should be off\n", privcid);
00983 privdb_val = AST_PRIVACY_ALLOW;
00984 }
00985 else if(ast_test_flag(&opts, OPT_SCREEN_NOCLID) && strncmp(privcid,"NOCALLERID",10) == 0 ) {
00986 if (option_verbose > 2)
00987 ast_verbose( VERBOSE_PREFIX_3 "CallerID blank; N option set; Screening should happen; dbval is %d\n", privdb_val);
00988 }
00989
00990 if(privdb_val == AST_PRIVACY_DENY ) {
00991 ast_copy_string(status, "NOANSWER", sizeof(status));
00992 if (option_verbose > 2)
00993 ast_verbose( VERBOSE_PREFIX_3 "Privacy DB reports PRIVACY_DENY for this callerid. Dial reports unavailable\n");
00994 res=0;
00995 goto out;
00996 }
00997 else if(privdb_val == AST_PRIVACY_KILL ) {
00998 ast_copy_string(status, "DONTCALL", sizeof(status));
00999 if (ast_opt_priority_jumping || ast_test_flag(&opts, OPT_PRIORITY_JUMP)) {
01000 ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 201);
01001 }
01002 res = 0;
01003 goto out;
01004 }
01005 else if(privdb_val == AST_PRIVACY_TORTURE ) {
01006 ast_copy_string(status, "TORTURE", sizeof(status));
01007 if (ast_opt_priority_jumping || ast_test_flag(&opts, OPT_PRIORITY_JUMP)) {
01008 ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 301);
01009 }
01010 res = 0;
01011 goto out;
01012 }
01013 else if(privdb_val == AST_PRIVACY_UNKNOWN ) {
01014
01015
01016
01017
01018
01019 snprintf(privintro, sizeof(privintro), "%s/sounds/priv-callerintros", ast_config_AST_DATA_DIR);
01020 if (mkdir(privintro, 0755) && errno != EEXIST) {
01021 ast_log(LOG_WARNING, "privacy: can't create directory priv-callerintros: %s\n", strerror(errno));
01022 res = -1;
01023 goto out;
01024 }
01025
01026 snprintf(privintro,sizeof(privintro), "priv-callerintros/%s", privcid);
01027 if( ast_fileexists(privintro,NULL,NULL ) > 0 && strncmp(privcid,"NOCALLERID",10) != 0) {
01028
01029
01030
01031 }
01032 else {
01033 int duration;
01034
01035
01036
01037
01038
01039
01040
01041 ast_answer(chan);
01042 res = ast_play_and_record(chan, "priv-recordintro", privintro, 4, "gsm", &duration, 128, 2000, 0);
01043
01044
01045 if (res == -1) {
01046
01047 ast_filedelete(privintro, NULL);
01048 if( ast_fileexists(privintro,NULL,NULL ) > 0 )
01049 ast_log(LOG_NOTICE,"privacy: ast_filedelete didn't do its job on %s\n", privintro);
01050 else if (option_verbose > 2)
01051 ast_verbose( VERBOSE_PREFIX_3 "Successfully deleted %s intro file\n", privintro);
01052 goto out;
01053 }
01054 if( !ast_streamfile(chan, "vm-dialout", chan->language) )
01055 ast_waitstream(chan, "");
01056 }
01057 }
01058 }
01059
01060 if (continue_exec)
01061 *continue_exec = 0;
01062
01063
01064 if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP_ONCE"))) {
01065 outbound_group = ast_strdupa(outbound_group);
01066 pbx_builtin_setvar_helper(chan, "OUTBOUND_GROUP_ONCE", NULL);
01067 } else {
01068 outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP");
01069 }
01070
01071 ast_copy_flags(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID | OPT_CALLER_HANGUP | OPT_IGNORE_FORWARDING);
01072
01073 rest = args.peers;
01074 while ((cur = strsep(&rest, "&")) ) {
01075 struct dial_localuser *tmp;
01076
01077 char *number = cur;
01078 char *tech = strsep(&number, "/");
01079 if (!number) {
01080 ast_log(LOG_WARNING, "Dial argument takes format (technology/[device:]number1)\n");
01081 goto out;
01082 }
01083 if (!(tmp = ast_calloc(1, sizeof(*tmp))))
01084 goto out;
01085 if (opts.flags) {
01086 ast_copy_flags(tmp, &opts,
01087 OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
01088 OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
01089 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
01090 OPT_CALLEE_PARK | OPT_CALLER_PARK |
01091 OPT_RINGBACK | OPT_MUSICBACK | OPT_FORCECLID);
01092 ast_set2_flag(tmp, args.url, DIAL_NOFORWARDHTML);
01093 }
01094 ast_copy_string(numsubst, number, sizeof(numsubst));
01095
01096 tmp->chan = ast_request(tech, chan->nativeformats, numsubst, &cause);
01097 if (!tmp->chan) {
01098
01099 ast_log(LOG_WARNING, "Unable to create channel of type '%s' (cause %d - %s)\n", tech, cause, ast_cause2str(cause));
01100 HANDLE_CAUSE(cause, chan);
01101 if (!rest)
01102 chan->hangupcause = cause;
01103 free(tmp);
01104 continue;
01105 }
01106 pbx_builtin_setvar_helper(tmp->chan, "DIALEDPEERNUMBER", numsubst);
01107 if (!ast_strlen_zero(tmp->chan->call_forward)) {
01108 char tmpchan[256];
01109 char *stuff;
01110 char *tech;
01111 ast_copy_string(tmpchan, tmp->chan->call_forward, sizeof(tmpchan));
01112 if ((stuff = strchr(tmpchan, '/'))) {
01113 *stuff++ = '\0';
01114 tech = tmpchan;
01115 } else {
01116 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", tmp->chan->call_forward, tmp->chan->context);
01117 stuff = tmpchan;
01118 tech = "Local";
01119 }
01120 tmp->forwards++;
01121 if (tmp->forwards < AST_MAX_FORWARDS) {
01122 if (option_verbose > 2)
01123 ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n", chan->name, tech, stuff, tmp->chan->name);
01124 ast_hangup(tmp->chan);
01125
01126 if (ast_test_flag(&opts, OPT_IGNORE_FORWARDING)) {
01127 tmp->chan = NULL;
01128 cause = AST_CAUSE_BUSY;
01129 if (option_verbose > 2)
01130 ast_verbose(VERBOSE_PREFIX_3 "Forwarding %s to '%s/%s' prevented.\n", chan->name, tech, stuff);
01131 } else {
01132 tmp->chan = ast_request(tech, chan->nativeformats, stuff, &cause);
01133 }
01134 if (!tmp->chan)
01135 ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause);
01136 else
01137 ast_channel_inherit_variables(chan, tmp->chan);
01138 } else {
01139 if (option_verbose > 2)
01140 ast_verbose(VERBOSE_PREFIX_3 "Too many forwards from %s\n", tmp->chan->name);
01141 ast_hangup(tmp->chan);
01142 tmp->chan = NULL;
01143 cause = AST_CAUSE_CONGESTION;
01144 }
01145 if (!tmp->chan) {
01146 HANDLE_CAUSE(cause, chan);
01147 free(tmp);
01148 continue;
01149 }
01150 }
01151
01152
01153 ast_rtp_make_compatible(tmp->chan, chan, !outgoing && !rest);
01154
01155
01156 ast_channel_inherit_variables(chan, tmp->chan);
01157
01158 tmp->chan->appl = "AppDial";
01159 tmp->chan->data = "(Outgoing Line)";
01160 tmp->chan->whentohangup = 0;
01161
01162 if (tmp->chan->cid.cid_num)
01163 free(tmp->chan->cid.cid_num);
01164 tmp->chan->cid.cid_num = ast_strdup(chan->cid.cid_num);
01165
01166 if (tmp->chan->cid.cid_name)
01167 free(tmp->chan->cid.cid_name);
01168 tmp->chan->cid.cid_name = ast_strdup(chan->cid.cid_name);
01169
01170 if (tmp->chan->cid.cid_ani)
01171 free(tmp->chan->cid.cid_ani);
01172 tmp->chan->cid.cid_ani = ast_strdup(chan->cid.cid_ani);
01173
01174 if (tmp->chan->cid.cid_dnid)
01175 free(tmp->chan->cid.cid_dnid);
01176
01177 tmp->chan->cid.cid_dnid = ast_strdup(chan->cid.cid_dnid);
01178
01179
01180 ast_string_field_set(tmp->chan, language, chan->language);
01181 ast_string_field_set(tmp->chan, accountcode, chan->accountcode);
01182 tmp->chan->cdrflags = chan->cdrflags;
01183 if (ast_strlen_zero(tmp->chan->musicclass))
01184 ast_string_field_set(tmp->chan, musicclass, chan->musicclass);
01185
01186 tmp->chan->cid.cid_rdnis = ast_strdup(chan->cid.cid_rdnis);
01187
01188 tmp->chan->cid.cid_pres = chan->cid.cid_pres;
01189
01190 tmp->chan->cid.cid_ton = chan->cid.cid_ton;
01191
01192 tmp->chan->cid.cid_tns = chan->cid.cid_tns;
01193
01194 tmp->chan->adsicpe = chan->adsicpe;
01195
01196 tmp->chan->transfercapability = chan->transfercapability;
01197
01198
01199 if (outbound_group)
01200 ast_app_group_set_channel(tmp->chan, outbound_group);
01201
01202
01203 if (!ast_strlen_zero(chan->macrocontext))
01204 ast_copy_string(tmp->chan->dialcontext, chan->macrocontext, sizeof(tmp->chan->dialcontext));
01205 else
01206 ast_copy_string(tmp->chan->dialcontext, chan->context, sizeof(tmp->chan->dialcontext));
01207 if (!ast_strlen_zero(chan->macroexten))
01208 ast_copy_string(tmp->chan->exten, chan->macroexten, sizeof(tmp->chan->exten));
01209 else
01210 ast_copy_string(tmp->chan->exten, chan->exten, sizeof(tmp->chan->exten));
01211
01212
01213 res = ast_call(tmp->chan, numsubst, 0);
01214
01215
01216 if (chan->cdr)
01217 ast_cdr_setdestchan(chan->cdr, tmp->chan->name);
01218
01219
01220 if (res) {
01221
01222 if (option_debug)
01223 ast_log(LOG_DEBUG, "ast call on peer returned %d\n", res);
01224 if (option_verbose > 2)
01225 ast_verbose(VERBOSE_PREFIX_3 "Couldn't call %s\n", numsubst);
01226 ast_hangup(tmp->chan);
01227 tmp->chan = NULL;
01228 free(tmp);
01229 continue;
01230 } else {
01231 senddialevent(chan, tmp->chan);
01232 if (option_verbose > 2)
01233 ast_verbose(VERBOSE_PREFIX_3 "Called %s\n", numsubst);
01234 if (!ast_test_flag(peerflags, OPT_ORIGINAL_CLID))
01235 ast_set_callerid(tmp->chan, S_OR(chan->macroexten, chan->exten), get_cid_name(cidname, sizeof(cidname), chan), NULL);
01236 }
01237
01238
01239
01240 ast_set_flag(tmp, DIAL_STILLGOING);
01241 tmp->next = outgoing;
01242 outgoing = tmp;
01243
01244 if (outgoing->chan->_state == AST_STATE_UP)
01245 break;
01246 }
01247
01248 if (ast_strlen_zero(args.timeout)) {
01249 to = -1;
01250 } else {
01251 to = atoi(args.timeout);
01252 if (to > 0)
01253 to *= 1000;
01254 else
01255 ast_log(LOG_WARNING, "Invalid timeout specified: '%s'\n", args.timeout);
01256 }
01257
01258 if (!outgoing) {
01259 strcpy(status, "CHANUNAVAIL");
01260 } else {
01261
01262 strcpy(status, "NOANSWER");
01263 if (ast_test_flag(outgoing, OPT_MUSICBACK)) {
01264 moh = 1;
01265 if (!ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
01266 char *original_moh = ast_strdupa(chan->musicclass);
01267 ast_string_field_set(chan, musicclass, opt_args[OPT_ARG_MUSICBACK]);
01268 ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
01269 ast_string_field_set(chan, musicclass, original_moh);
01270 } else {
01271 ast_moh_start(chan, NULL, NULL);
01272 }
01273 ast_indicate(chan, AST_CONTROL_PROGRESS);
01274 } else if (ast_test_flag(outgoing, OPT_RINGBACK)) {
01275 ast_indicate(chan, AST_CONTROL_RINGING);
01276 sentringing++;
01277 }
01278 }
01279
01280 time(&start_time);
01281 peer = wait_for_answer(chan, outgoing, &to, peerflags, &sentringing, status, sizeof(status), numbusy, numnochan, numcongestion, ast_test_flag(&opts, OPT_PRIORITY_JUMP), &result);
01282
01283 if (!peer) {
01284 if (result) {
01285 res = result;
01286 } else if (to) {
01287 res = -1;
01288 } else {
01289 res = 0;
01290 }
01291
01292 } else {
01293 const char *number;
01294 time_t end_time, answer_time = time(NULL);
01295
01296 strcpy(status, "ANSWER");
01297
01298
01299
01300 hanguptree(outgoing, peer);
01301 outgoing = NULL;
01302
01303 if (chan->cdr)
01304 ast_cdr_setdestchan(chan->cdr, peer->name);
01305 if (peer->name)
01306 pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", peer->name);
01307
01308 number = pbx_builtin_getvar_helper(peer, "DIALEDPEERNUMBER");
01309 if (!number)
01310 number = numsubst;
01311 pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", number);
01312 if (!ast_strlen_zero(args.url) && ast_channel_supports_html(peer) ) {
01313 if (option_debug)
01314 ast_log(LOG_DEBUG, "app_dial: sendurl=%s.\n", args.url);
01315 ast_channel_sendurl( peer, args.url );
01316 }
01317 if ( (ast_test_flag(&opts, OPT_PRIVACY) || ast_test_flag(&opts, OPT_SCREENING)) && privdb_val == AST_PRIVACY_UNKNOWN) {
01318 int res2;
01319 int loopcount = 0;
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329 if (ast_test_flag(&opts, OPT_MUSICBACK) && !ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
01330 char *original_moh = ast_strdupa(chan->musicclass);
01331 ast_indicate(chan, -1);
01332 ast_string_field_set(chan, musicclass, opt_args[OPT_ARG_MUSICBACK]);
01333 ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
01334 ast_string_field_set(chan, musicclass, original_moh);
01335 } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
01336 ast_indicate(chan, AST_CONTROL_RINGING);
01337 sentringing++;
01338 }
01339
01340
01341 res2 = ast_autoservice_start(chan);
01342
01343 for (loopcount = 0; loopcount < 3; loopcount++) {
01344 if (res2 && loopcount == 0)
01345 break;
01346 if (!res2)
01347 res2 = ast_play_and_wait(peer,"priv-callpending");
01348 if (!valid_priv_reply(&opts, res2))
01349 res2 = 0;
01350
01351
01352
01353 if (!res2)
01354 res2 = ast_play_and_wait(peer,privintro);
01355 if (!valid_priv_reply(&opts, res2))
01356 res2 = 0;
01357
01358 if( !res2 ) {
01359
01360 if( ast_test_flag(&opts, OPT_PRIVACY) )
01361 res2 = ast_play_and_wait(peer,"priv-callee-options");
01362 if( ast_test_flag(&opts, OPT_SCREENING) )
01363 res2 = ast_play_and_wait(peer,"screen-callee-options");
01364 }
01365
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381 if (valid_priv_reply(&opts, res2))
01382 break;
01383
01384 res2 = ast_play_and_wait(peer, "vm-sorry");
01385 }
01386
01387 if (ast_test_flag(&opts, OPT_MUSICBACK)) {
01388 ast_moh_stop(chan);
01389 } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
01390 ast_indicate(chan, -1);
01391 sentringing=0;
01392 }
01393 ast_autoservice_stop(chan);
01394
01395 switch (res2) {
01396 case '1':
01397 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
01398 if (option_verbose > 2)
01399 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to ALLOW\n",
01400 opt_args[OPT_ARG_PRIVACY], privcid);
01401 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_ALLOW);
01402 }
01403 break;
01404 case '2':
01405 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
01406 if (option_verbose > 2)
01407 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to DENY\n",
01408 opt_args[OPT_ARG_PRIVACY], privcid);
01409 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_DENY);
01410 }
01411 ast_copy_string(status, "NOANSWER", sizeof(status));
01412 ast_hangup(peer);
01413 res=0;
01414 goto out;
01415 case '3':
01416 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
01417 if (option_verbose > 2)
01418 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to TORTURE\n",
01419 opt_args[OPT_ARG_PRIVACY], privcid);
01420 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_TORTURE);
01421 }
01422 ast_copy_string(status, "TORTURE", sizeof(status));
01423
01424 res = 0;
01425 ast_hangup(peer);
01426 goto out;
01427 case '4':
01428 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
01429 if (option_verbose > 2)
01430 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to KILL\n",
01431 opt_args[OPT_ARG_PRIVACY], privcid);
01432 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_KILL);
01433 }
01434
01435 ast_copy_string(status, "DONTCALL", sizeof(status));
01436 res = 0;
01437 ast_hangup(peer);
01438 goto out;
01439 case '5':
01440 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
01441 if (option_verbose > 2)
01442 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to ALLOW\n",
01443 opt_args[OPT_ARG_PRIVACY], privcid);
01444 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_ALLOW);
01445 ast_hangup(peer);
01446 res=0;
01447 goto out;
01448 }
01449 default:
01450
01451
01452
01453
01454 ast_log(LOG_NOTICE, "privacy: no valid response from the callee. Sending the caller to voicemail, the callee isn't responding\n");
01455 ast_hangup(peer);
01456 res=0;
01457 goto out;
01458 }
01459
01460
01461
01462
01463
01464
01465
01466 if( strncmp(privcid,"NOCALLERID",10) == 0 || ast_test_flag(&opts, OPT_SCREEN_NOINTRO) ) {
01467 ast_filedelete(privintro, NULL);
01468 if( ast_fileexists(privintro, NULL, NULL ) > 0 )
01469 ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", privintro);
01470 else if (option_verbose > 2)
01471 ast_verbose(VERBOSE_PREFIX_3 "Successfully deleted %s intro file\n", privintro);
01472 }
01473 }
01474 if (!ast_test_flag(&opts, OPT_ANNOUNCE) || ast_strlen_zero(opt_args[OPT_ARG_ANNOUNCE])) {
01475 res = 0;
01476 } else {
01477 int digit = 0;
01478
01479 res = ast_autoservice_start(chan);
01480
01481 if (!res)
01482 res = ast_streamfile(peer, opt_args[OPT_ARG_ANNOUNCE], peer->language);
01483 if (!res) {
01484 digit = ast_waitstream(peer, AST_DIGIT_ANY);
01485 }
01486
01487 res = ast_autoservice_stop(chan);
01488 if (digit > 0 && !res)
01489 res = ast_senddigit(chan, digit);
01490 else
01491 res = digit;
01492
01493 }
01494
01495 if (chan && peer && ast_test_flag(&opts, OPT_GOTO) && !ast_strlen_zero(opt_args[OPT_ARG_GOTO])) {
01496 replace_macro_delimiter(opt_args[OPT_ARG_GOTO]);
01497 ast_parseable_goto(chan, opt_args[OPT_ARG_GOTO]);
01498 ast_parseable_goto(peer, opt_args[OPT_ARG_GOTO]);
01499 peer->priority++;
01500 ast_pbx_start(peer);
01501 hanguptree(outgoing, NULL);
01502 if (continue_exec)
01503 *continue_exec = 1;
01504 res = 0;
01505 goto done;
01506 }
01507
01508 if (ast_test_flag(&opts, OPT_CALLEE_MACRO) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_MACRO])) {
01509 struct ast_app *theapp;
01510 const char *macro_result;
01511
01512 res = ast_autoservice_start(chan);
01513 if (res) {
01514 ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
01515 res = -1;
01516 }
01517
01518 theapp = pbx_findapp("Macro");
01519
01520 if (theapp && !res) {
01521 replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_MACRO]);
01522 res = pbx_exec(peer, theapp, opt_args[OPT_ARG_CALLEE_MACRO]);
01523 ast_log(LOG_DEBUG, "Macro exited with status %d\n", res);
01524 res = 0;
01525 } else {
01526 ast_log(LOG_ERROR, "Could not find application Macro\n");
01527 res = -1;
01528 }
01529
01530 if (ast_autoservice_stop(chan) < 0) {
01531 ast_log(LOG_ERROR, "Could not stop autoservice on calling channel\n");
01532 res = -1;
01533 }
01534
01535 if (!res && (macro_result = pbx_builtin_getvar_helper(peer, "MACRO_RESULT"))) {
01536 char *macro_transfer_dest;
01537
01538 if (!strcasecmp(macro_result, "BUSY")) {
01539 ast_copy_string(status, macro_result, sizeof(status));
01540 if (ast_opt_priority_jumping || ast_test_flag(&opts, OPT_PRIORITY_JUMP)) {
01541 if (!ast_goto_if_exists(chan, NULL, NULL, chan->priority + 101)) {
01542 ast_set_flag(peerflags, OPT_GO_ON);
01543 }
01544 } else
01545 ast_set_flag(peerflags, OPT_GO_ON);
01546 res = -1;
01547 } else if (!strcasecmp(macro_result, "CONGESTION") || !strcasecmp(macro_result, "CHANUNAVAIL")) {
01548 ast_copy_string(status, macro_result, sizeof(status));
01549 ast_set_flag(peerflags, OPT_GO_ON);
01550 res = -1;
01551 } else if (!strcasecmp(macro_result, "CONTINUE")) {
01552
01553
01554
01555
01556 ast_set_flag(peerflags, OPT_GO_ON);
01557 res = -1;
01558 } else if (!strcasecmp(macro_result, "ABORT")) {
01559
01560 res = -1;
01561 } else if (!strncasecmp(macro_result, "GOTO:", 5) && (macro_transfer_dest = ast_strdupa(macro_result + 5))) {
01562 res = -1;
01563
01564 if (strchr(macro_transfer_dest, '^')) {
01565 replace_macro_delimiter(macro_transfer_dest);
01566 if (!ast_parseable_goto(chan, macro_transfer_dest))
01567 ast_set_flag(peerflags, OPT_GO_ON);
01568
01569 }
01570 }
01571 }
01572 }
01573
01574 if (!res) {
01575 if (calldurationlimit > 0) {
01576 chan->whentohangup = time(NULL) + calldurationlimit;
01577 }
01578 if (!ast_strlen_zero(dtmfcalled)) {
01579 if (option_verbose > 2)
01580 ast_verbose(VERBOSE_PREFIX_3 "Sending DTMF '%s' to the called party.\n", dtmfcalled);
01581 res = ast_dtmf_stream(peer,chan,dtmfcalled,250);
01582 }
01583 if (!ast_strlen_zero(dtmfcalling)) {
01584 if (option_verbose > 2)
01585 ast_verbose(VERBOSE_PREFIX_3 "Sending DTMF '%s' to the calling party.\n", dtmfcalling);
01586 res = ast_dtmf_stream(chan,peer,dtmfcalling,250);
01587 }
01588 }
01589
01590 if (!res) {
01591 struct ast_bridge_config config;
01592
01593 memset(&config,0,sizeof(struct ast_bridge_config));
01594 if (play_to_caller)
01595 ast_set_flag(&(config.features_caller), AST_FEATURE_PLAY_WARNING);
01596 if (play_to_callee)
01597 ast_set_flag(&(config.features_callee), AST_FEATURE_PLAY_WARNING);
01598 if (ast_test_flag(peerflags, OPT_CALLEE_TRANSFER))
01599 ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
01600 if (ast_test_flag(peerflags, OPT_CALLER_TRANSFER))
01601 ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
01602 if (ast_test_flag(peerflags, OPT_CALLEE_HANGUP))
01603 ast_set_flag(&(config.features_callee), AST_FEATURE_DISCONNECT);
01604 if (ast_test_flag(peerflags, OPT_CALLER_HANGUP))
01605 ast_set_flag(&(config.features_caller), AST_FEATURE_DISCONNECT);
01606 if (ast_test_flag(peerflags, OPT_CALLEE_MONITOR))
01607 ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMON);
01608 if (ast_test_flag(peerflags, OPT_CALLER_MONITOR))
01609 ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMON);
01610 if (ast_test_flag(peerflags, OPT_CALLEE_PARK))
01611 ast_set_flag(&(config.features_callee), AST_FEATURE_PARKCALL);
01612 if (ast_test_flag(peerflags, OPT_CALLER_PARK))
01613 ast_set_flag(&(config.features_caller), AST_FEATURE_PARKCALL);
01614
01615 config.timelimit = timelimit;
01616 config.play_warning = play_warning;
01617 config.warning_freq = warning_freq;
01618 config.warning_sound = warning_sound;
01619 config.end_sound = end_sound;
01620 config.start_sound = start_sound;
01621 if (moh) {
01622 moh = 0;
01623 ast_moh_stop(chan);
01624 } else if (sentringing) {
01625 sentringing = 0;
01626 ast_indicate(chan, -1);
01627 }
01628
01629 ast_deactivate_generator(chan);
01630
01631 res = ast_channel_make_compatible(chan, peer);
01632 if (res < 0) {
01633 ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", chan->name, peer->name);
01634 ast_hangup(peer);
01635 res = -1;
01636 goto done;
01637 }
01638 if (opermode && (!strncmp(chan->name,"Zap",3)) &&
01639 (!strncmp(peer->name,"Zap",3)))
01640 {
01641 struct oprmode oprmode;
01642
01643 oprmode.peer = peer;
01644 oprmode.mode = opermode;
01645
01646 ast_channel_setoption(chan,
01647 AST_OPTION_OPRMODE,&oprmode,sizeof(struct oprmode),0);
01648 }
01649 res = ast_bridge_call(chan,peer,&config);
01650 time(&end_time);
01651 {
01652 char toast[80];
01653 snprintf(toast, sizeof(toast), "%ld", (long)(end_time - answer_time));
01654 pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", toast);
01655 }
01656 } else {
01657 time(&end_time);
01658 res = -1;
01659 }
01660 {
01661 char toast[80];
01662 snprintf(toast, sizeof(toast), "%ld", (long)(end_time - start_time));
01663 pbx_builtin_setvar_helper(chan, "DIALEDTIME", toast);
01664 }
01665
01666 if (res != AST_PBX_NO_HANGUP_PEER) {
01667 if (!chan->_softhangup)
01668 chan->hangupcause = peer->hangupcause;
01669 ast_hangup(peer);
01670 }
01671 }
01672 out:
01673 if (moh) {
01674 moh = 0;
01675 ast_moh_stop(chan);
01676 } else if (sentringing) {
01677 sentringing = 0;
01678 ast_indicate(chan, -1);
01679 }
01680 ast_rtp_early_bridge(chan, NULL);
01681 hanguptree(outgoing, NULL);
01682 pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
01683 if (option_debug)
01684 ast_log(LOG_DEBUG, "Exiting with DIALSTATUS=%s.\n", status);
01685
01686 if ((ast_test_flag(peerflags, OPT_GO_ON)) && (!chan->_softhangup) && (res != AST_PBX_KEEPALIVE))
01687 res = 0;
01688
01689 done:
01690 ast_module_user_remove(u);
01691 return res;
01692 }
01693
01694 static int dial_exec(struct ast_channel *chan, void *data)
01695 {
01696 struct ast_flags peerflags;
01697
01698 memset(&peerflags, 0, sizeof(peerflags));
01699
01700 return dial_exec_full(chan, data, &peerflags, NULL);
01701 }
01702
01703 static int retrydial_exec(struct ast_channel *chan, void *data)
01704 {
01705 char *announce = NULL, *dialdata = NULL;
01706 const char *context = NULL;
01707 int sleep = 0, loops = 0, res = -1;
01708 struct ast_module_user *u;
01709 struct ast_flags peerflags;
01710
01711 if (ast_strlen_zero(data)) {
01712 ast_log(LOG_WARNING, "RetryDial requires an argument!\n");
01713 return -1;
01714 }
01715
01716 u = ast_module_user_add(chan);
01717
01718 announce = ast_strdupa(data);
01719
01720 memset(&peerflags, 0, sizeof(peerflags));
01721
01722 if ((dialdata = strchr(announce, '|'))) {
01723 *dialdata++ = '\0';
01724 if ((sleep = atoi(dialdata))) {
01725 sleep *= 1000;
01726 } else {
01727 ast_log(LOG_ERROR, "%s requires the numerical argument <sleep>\n",rapp);
01728 goto done;
01729 }
01730 if ((dialdata = strchr(dialdata, '|'))) {
01731 *dialdata++ = '\0';
01732 if (!(loops = atoi(dialdata))) {
01733 ast_log(LOG_ERROR, "%s requires the numerical argument <loops>\n",rapp);
01734 goto done;
01735 }
01736 }
01737 }
01738
01739 if ((dialdata = strchr(dialdata, '|'))) {
01740 *dialdata++ = '\0';
01741 } else {
01742 ast_log(LOG_ERROR, "%s requires more arguments\n",rapp);
01743 goto done;
01744 }
01745
01746 if (sleep < 1000)
01747 sleep = 10000;
01748
01749 if (!loops)
01750 loops = -1;
01751
01752 context = pbx_builtin_getvar_helper(chan, "EXITCONTEXT");
01753
01754 res = 0;
01755 while (loops) {
01756 int continue_exec;
01757
01758 chan->data = "Retrying";
01759 if (ast_test_flag(chan, AST_FLAG_MOH))
01760 ast_moh_stop(chan);
01761
01762 res = dial_exec_full(chan, dialdata, &peerflags, &continue_exec);
01763 if (continue_exec)
01764 break;
01765 if (res == 0) {
01766 if (ast_test_flag(&peerflags, OPT_DTMF_EXIT)) {
01767 if (!(res = ast_streamfile(chan, announce, chan->language)))
01768 res = ast_waitstream(chan, AST_DIGIT_ANY);
01769 if (!res && sleep) {
01770 if (!ast_test_flag(chan, AST_FLAG_MOH))
01771 ast_moh_start(chan, NULL, NULL);
01772 res = ast_waitfordigit(chan, sleep);
01773 }
01774 } else {
01775 if (!(res = ast_streamfile(chan, announce, chan->language)))
01776 res = ast_waitstream(chan, "");
01777 if (sleep) {
01778 if (!ast_test_flag(chan, AST_FLAG_MOH))
01779 ast_moh_start(chan, NULL, NULL);
01780 if (!res)
01781 res = ast_waitfordigit(chan, sleep);
01782 }
01783 }
01784 }
01785
01786 if (res < 0)
01787 break;
01788 else if (res > 0) {
01789 if (onedigit_goto(chan, context, (char) res, 1)) {
01790 res = 0;
01791 break;
01792 }
01793 }
01794 loops--;
01795 }
01796 if (loops == 0)
01797 res = 0;
01798 else if (res == 1)
01799 res = 0;
01800
01801 if (ast_test_flag(chan, AST_FLAG_MOH))
01802 ast_moh_stop(chan);
01803 done:
01804 ast_module_user_remove(u);
01805 return res;
01806 }
01807
01808 static int unload_module(void)
01809 {
01810 int res;
01811
01812 res = ast_unregister_application(app);
01813 res |= ast_unregister_application(rapp);
01814
01815 ast_module_user_hangup_all();
01816
01817 return res;
01818 }
01819
01820 static int load_module(void)
01821 {
01822 int res;
01823
01824 res = ast_register_application(app, dial_exec, synopsis, descrip);
01825 res |= ast_register_application(rapp, retrydial_exec, rsynopsis, rdescrip);
01826
01827 return res;
01828 }
01829
01830 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Dialing Application");