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