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: 119530 $")
00036
00037 #include <stdlib.h>
00038 #include <errno.h>
00039 #include <unistd.h>
00040 #include <string.h>
00041 #include <stdlib.h>
00042 #include <stdio.h>
00043 #include <sys/time.h>
00044 #include <sys/signal.h>
00045 #include <sys/stat.h>
00046 #include <netinet/in.h>
00047
00048 #include "asterisk/lock.h"
00049 #include "asterisk/file.h"
00050 #include "asterisk/logger.h"
00051 #include "asterisk/channel.h"
00052 #include "asterisk/pbx.h"
00053 #include "asterisk/options.h"
00054 #include "asterisk/module.h"
00055 #include "asterisk/translate.h"
00056 #include "asterisk/say.h"
00057 #include "asterisk/config.h"
00058 #include "asterisk/features.h"
00059 #include "asterisk/musiconhold.h"
00060 #include "asterisk/callerid.h"
00061 #include "asterisk/utils.h"
00062 #include "asterisk/app.h"
00063 #include "asterisk/causes.h"
00064 #include "asterisk/rtp.h"
00065 #include "asterisk/cdr.h"
00066 #include "asterisk/manager.h"
00067 #include "asterisk/privacy.h"
00068 #include "asterisk/stringfields.h"
00069 #include "asterisk/global_datastores.h"
00070
00071 static char *app = "Dial";
00072
00073 static char *synopsis = "Place a call and connect to the current channel";
00074
00075 static char *descrip =
00076 " Dial(Technology/resource[&Tech2/resource2...][|timeout][|options][|URL]):\n"
00077 "This application will place calls to one or more specified channels. As soon\n"
00078 "as one of the requested channels answers, the originating channel will be\n"
00079 "answered, if it has not already been answered. These two channels will then\n"
00080 "be active in a bridged call. All other channels that were requested will then\n"
00081 "be hung up.\n"
00082 " Unless there is a timeout specified, the Dial application will wait\n"
00083 "indefinitely until one of the called channels answers, the user hangs up, or\n"
00084 "if all of the called channels are busy or unavailable. Dialplan executing will\n"
00085 "continue if no requested channels can be called, or if the timeout expires.\n\n"
00086 " This application sets the following channel variables upon completion:\n"
00087 " DIALEDTIME - This is the time from dialing a channel until when it\n"
00088 " is disconnected.\n"
00089 " ANSWEREDTIME - This is the amount of time for actual call.\n"
00090 " DIALSTATUS - This is the status of the call:\n"
00091 " CHANUNAVAIL | CONGESTION | NOANSWER | BUSY | ANSWER | CANCEL\n"
00092 " DONTCALL | TORTURE | INVALIDARGS\n"
00093 " For the Privacy and Screening Modes, the DIALSTATUS variable will be set to\n"
00094 "DONTCALL if the called party chooses to send the calling party to the 'Go Away'\n"
00095 "script. The DIALSTATUS variable will be set to TORTURE if the called party\n"
00096 "wants to send the caller to the 'torture' script.\n"
00097 " This application will report normal termination if the originating channel\n"
00098 "hangs up, or if the call is bridged and either of the parties in the bridge\n"
00099 "ends the call.\n"
00100 " The optional URL will be sent to the called party if the channel supports it.\n"
00101 " If the OUTBOUND_GROUP variable is set, all peer channels created by this\n"
00102 "application will be put into that group (as in Set(GROUP()=...).\n"
00103 " If the OUTBOUND_GROUP_ONCE variable is set, all peer channels created by this\n"
00104 "application will be put into that group (as in Set(GROUP()=...). Unlike OUTBOUND_GROUP,\n"
00105 "however, the variable will be unset after use.\n\n"
00106 " Options:\n"
00107 " A(x) - Play an announcement to the called party, using 'x' as the file.\n"
00108 " C - Reset the CDR for this call.\n"
00109 " d - Allow the calling user to dial a 1 digit extension while waiting for\n"
00110 " a call to be answered. Exit to that extension if it exists in the\n"
00111 " current context, or the context defined in the EXITCONTEXT variable,\n"
00112 " if it exists.\n"
00113 " D([called][:calling]) - Send the specified DTMF strings *after* the called\n"
00114 " party has answered, but before the call gets bridged. The 'called'\n"
00115 " DTMF string is sent to the called party, and the 'calling' DTMF\n"
00116 " string is sent to the calling party. Both parameters can be used\n"
00117 " alone.\n"
00118 " f - Force the callerid of the *calling* channel to be set as the\n"
00119 " extension associated with the channel using a dialplan 'hint'.\n"
00120 " For example, some PSTNs do not allow CallerID to be set to anything\n"
00121 " other than the number assigned to the caller.\n"
00122 " g - Proceed with dialplan execution at the current extension if the\n"
00123 " destination channel hangs up.\n"
00124 " G(context^exten^pri) - If the call is answered, transfer the calling party to\n"
00125 " the specified priority and the called party to the specified priority+1.\n"
00126 " Optionally, an extension, or extension and context may be specified. \n"
00127 " Otherwise, the current extension is used. You cannot use any additional\n"
00128 " action post answer options in conjunction with this option.\n"
00129 " h - Allow the called party to hang up by sending the '*' DTMF digit.\n"
00130 " H - Allow the calling party to hang up by hitting the '*' DTMF digit.\n"
00131 " i - Asterisk will ignore any forwarding requests it may receive on this\n"
00132 " dial attempt.\n"
00133 " j - Jump to priority n+101 if all of the requested channels were busy.\n"
00134 " k - Allow the called party to enable parking of the call by sending\n"
00135 " the DTMF sequence defined for call parking in features.conf.\n"
00136 " K - Allow the calling party to enable parking of the call by sending\n"
00137 " the DTMF sequence defined for call parking in features.conf.\n"
00138 " L(x[:y][:z]) - Limit the call to 'x' ms. Play a warning when 'y' ms are\n"
00139 " left. Repeat the warning every 'z' ms. The following special\n"
00140 " variables can be used with this option:\n"
00141 " * LIMIT_PLAYAUDIO_CALLER yes|no (default yes)\n"
00142 " Play sounds to the caller.\n"
00143 " * LIMIT_PLAYAUDIO_CALLEE yes|no\n"
00144 " Play sounds to the callee.\n"
00145 " * LIMIT_TIMEOUT_FILE File to play when time is up.\n"
00146 " * LIMIT_CONNECT_FILE File to play when call begins.\n"
00147 " * LIMIT_WARNING_FILE File to play as warning if 'y' is defined.\n"
00148 " The default is to say the time remaining.\n"
00149 " m([class]) - Provide hold music to the calling party until a requested\n"
00150 " channel answers. A specific MusicOnHold class can be\n"
00151 " specified.\n"
00152 " M(x[^arg]) - Execute the Macro for the *called* channel before connecting\n"
00153 " to the calling channel. Arguments can be specified to the Macro\n"
00154 " using '^' as a delimeter. The Macro can set the variable\n"
00155 " MACRO_RESULT to specify the following actions after the Macro is\n"
00156 " finished executing.\n"
00157 " * ABORT Hangup both legs of the call.\n"
00158 " * CONGESTION Behave as if line congestion was encountered.\n"
00159 " * BUSY Behave as if a busy signal was encountered. This will also\n"
00160 " have the application jump to priority n+101 if the\n"
00161 " 'j' option is set.\n"
00162 " * CONTINUE Hangup the called party and allow the calling party\n"
00163 " to continue dialplan execution at the next priority.\n"
00164 " * GOTO:<context>^<exten>^<priority> - Transfer the call to the\n"
00165 " specified priority. Optionally, an extension, or\n"
00166 " extension and priority can be specified.\n"
00167 " You cannot use any additional action post answer options in conjunction\n"
00168 " with this option. Also, pbx services are not run on the peer (called) channel,\n"
00169 " so you will not be able to set timeouts via the TIMEOUT() function in this macro.\n"
00170 " n - This option is a modifier for the screen/privacy mode. It specifies\n"
00171 " that no introductions are to be saved in the priv-callerintros\n"
00172 " directory.\n"
00173 " N - This option is a modifier for the screen/privacy mode. It specifies\n"
00174 " that if callerID is present, do not screen the call.\n"
00175 " o - Specify that the CallerID that was present on the *calling* channel\n"
00176 " be set as the CallerID on the *called* channel. This was the\n"
00177 " behavior of Asterisk 1.0 and earlier.\n"
00178 " O([x]) - \"Operator Services\" mode (Zaptel channel to Zaptel channel\n"
00179 " only, if specified on non-Zaptel interface, it will be ignored).\n"
00180 " When the destination answers (presumably an operator services\n"
00181 " station), the originator no longer has control of their line.\n"
00182 " They may hang up, but the switch will not release their line\n"
00183 " until the destination party hangs up (the operator). Specified\n"
00184 " without an arg, or with 1 as an arg, the originator hanging up\n"
00185 " will cause the phone to ring back immediately. With a 2 specified,\n"
00186 " when the \"operator\" flashes the trunk, it will ring their phone\n"
00187 " back.\n"
00188 " p - This option enables screening mode. This is basically Privacy mode\n"
00189 " without memory.\n"
00190 " P([x]) - Enable privacy mode. Use 'x' as the family/key in the database if\n"
00191 " it is provided. The current extension is used if a database\n"
00192 " family/key is not specified.\n"
00193 " r - Indicate ringing to the calling party. Pass no audio to the calling\n"
00194 " party until the called channel has answered.\n"
00195 " S(x) - Hang up the call after 'x' seconds *after* the called party has\n"
00196 " answered the call.\n"
00197 " t - Allow the called party to transfer the calling party by sending the\n"
00198 " DTMF sequence defined in features.conf.\n"
00199 " T - Allow the calling party to transfer the called party by sending the\n"
00200 " DTMF sequence defined in features.conf.\n"
00201 " w - Allow the called party to enable recording of the call by sending\n"
00202 " the DTMF sequence defined for one-touch recording in features.conf.\n"
00203 " W - Allow the calling party to enable recording of the call by sending\n"
00204 " the DTMF sequence defined for one-touch recording in features.conf.\n";
00205
00206
00207 static char *rapp = "RetryDial";
00208 static char *rsynopsis = "Place a call, retrying on failure allowing optional exit extension.";
00209 static char *rdescrip =
00210 " RetryDial(announce|sleep|retries|dialargs): This application will attempt to\n"
00211 "place a call using the normal Dial application. If no channel can be reached,\n"
00212 "the 'announce' file will be played. Then, it will wait 'sleep' number of\n"
00213 "seconds before retrying the call. After 'retries' number of attempts, the\n"
00214 "calling channel will continue at the next priority in the dialplan. If the\n"
00215 "'retries' setting is set to 0, this application will retry endlessly.\n"
00216 " While waiting to retry a call, a 1 digit extension may be dialed. If that\n"
00217 "extension exists in either the context defined in ${EXITCONTEXT} or the current\n"
00218 "one, The call will jump to that extension immediately.\n"
00219 " The 'dialargs' are specified in the same format that arguments are provided\n"
00220 "to the Dial application.\n";
00221
00222 enum {
00223 OPT_ANNOUNCE = (1 << 0),
00224 OPT_RESETCDR = (1 << 1),
00225 OPT_DTMF_EXIT = (1 << 2),
00226 OPT_SENDDTMF = (1 << 3),
00227 OPT_FORCECLID = (1 << 4),
00228 OPT_GO_ON = (1 << 5),
00229 OPT_CALLEE_HANGUP = (1 << 6),
00230 OPT_CALLER_HANGUP = (1 << 7),
00231 OPT_PRIORITY_JUMP = (1 << 8),
00232 OPT_DURATION_LIMIT = (1 << 9),
00233 OPT_MUSICBACK = (1 << 10),
00234 OPT_CALLEE_MACRO = (1 << 11),
00235 OPT_SCREEN_NOINTRO = (1 << 12),
00236 OPT_SCREEN_NOCLID = (1 << 13),
00237 OPT_ORIGINAL_CLID = (1 << 14),
00238 OPT_SCREENING = (1 << 15),
00239 OPT_PRIVACY = (1 << 16),
00240 OPT_RINGBACK = (1 << 17),
00241 OPT_DURATION_STOP = (1 << 18),
00242 OPT_CALLEE_TRANSFER = (1 << 19),
00243 OPT_CALLER_TRANSFER = (1 << 20),
00244 OPT_CALLEE_MONITOR = (1 << 21),
00245 OPT_CALLER_MONITOR = (1 << 22),
00246 OPT_GOTO = (1 << 23),
00247 OPT_OPERMODE = (1 << 24),
00248 OPT_CALLEE_PARK = (1 << 25),
00249 OPT_CALLER_PARK = (1 << 26),
00250 OPT_IGNORE_FORWARDING = (1 << 27),
00251 } dial_exec_option_flags;
00252
00253 #define DIAL_STILLGOING (1 << 30)
00254 #define DIAL_NOFORWARDHTML (1 << 31)
00255
00256 enum {
00257 OPT_ARG_ANNOUNCE = 0,
00258 OPT_ARG_SENDDTMF,
00259 OPT_ARG_GOTO,
00260 OPT_ARG_DURATION_LIMIT,
00261 OPT_ARG_MUSICBACK,
00262 OPT_ARG_CALLEE_MACRO,
00263 OPT_ARG_PRIVACY,
00264 OPT_ARG_DURATION_STOP,
00265 OPT_ARG_OPERMODE,
00266
00267 OPT_ARG_ARRAY_SIZE,
00268 } dial_exec_option_args;
00269
00270 AST_APP_OPTIONS(dial_exec_options, {
00271 AST_APP_OPTION_ARG('A', OPT_ANNOUNCE, OPT_ARG_ANNOUNCE),
00272 AST_APP_OPTION('C', OPT_RESETCDR),
00273 AST_APP_OPTION('d', OPT_DTMF_EXIT),
00274 AST_APP_OPTION_ARG('D', OPT_SENDDTMF, OPT_ARG_SENDDTMF),
00275 AST_APP_OPTION('f', OPT_FORCECLID),
00276 AST_APP_OPTION('g', OPT_GO_ON),
00277 AST_APP_OPTION_ARG('G', OPT_GOTO, OPT_ARG_GOTO),
00278 AST_APP_OPTION('h', OPT_CALLEE_HANGUP),
00279 AST_APP_OPTION('H', OPT_CALLER_HANGUP),
00280 AST_APP_OPTION('i', OPT_IGNORE_FORWARDING),
00281 AST_APP_OPTION('j', OPT_PRIORITY_JUMP),
00282 AST_APP_OPTION('k', OPT_CALLEE_PARK),
00283 AST_APP_OPTION('K', OPT_CALLER_PARK),
00284 AST_APP_OPTION_ARG('L', OPT_DURATION_LIMIT, OPT_ARG_DURATION_LIMIT),
00285 AST_APP_OPTION_ARG('m', OPT_MUSICBACK, OPT_ARG_MUSICBACK),
00286 AST_APP_OPTION_ARG('M', OPT_CALLEE_MACRO, OPT_ARG_CALLEE_MACRO),
00287 AST_APP_OPTION('n', OPT_SCREEN_NOINTRO),
00288 AST_APP_OPTION('N', OPT_SCREEN_NOCLID),
00289 AST_APP_OPTION('o', OPT_ORIGINAL_CLID),
00290 AST_APP_OPTION_ARG('O', OPT_OPERMODE,OPT_ARG_OPERMODE),
00291 AST_APP_OPTION('p', OPT_SCREENING),
00292 AST_APP_OPTION_ARG('P', OPT_PRIVACY, OPT_ARG_PRIVACY),
00293 AST_APP_OPTION('r', OPT_RINGBACK),
00294 AST_APP_OPTION_ARG('S', OPT_DURATION_STOP, OPT_ARG_DURATION_STOP),
00295 AST_APP_OPTION('t', OPT_CALLEE_TRANSFER),
00296 AST_APP_OPTION('T', OPT_CALLER_TRANSFER),
00297 AST_APP_OPTION('w', OPT_CALLEE_MONITOR),
00298 AST_APP_OPTION('W', OPT_CALLER_MONITOR),
00299 });
00300
00301 #define CAN_EARLY_BRIDGE(flags) (!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
01216 ast_string_field_set(tmp->chan, language, chan->language);
01217 ast_string_field_set(tmp->chan, accountcode, chan->accountcode);
01218 tmp->chan->cdrflags = chan->cdrflags;
01219 if (ast_strlen_zero(tmp->chan->musicclass))
01220 ast_string_field_set(tmp->chan, musicclass, chan->musicclass);
01221
01222 tmp->chan->cid.cid_rdnis = ast_strdup(chan->cid.cid_rdnis);
01223
01224 tmp->chan->cid.cid_pres = chan->cid.cid_pres;
01225
01226 tmp->chan->cid.cid_ton = chan->cid.cid_ton;
01227
01228 tmp->chan->cid.cid_tns = chan->cid.cid_tns;
01229
01230 tmp->chan->adsicpe = chan->adsicpe;
01231
01232 tmp->chan->transfercapability = chan->transfercapability;
01233
01234
01235 if (outbound_group)
01236 ast_app_group_set_channel(tmp->chan, outbound_group);
01237
01238
01239 if (!ast_strlen_zero(chan->macrocontext))
01240 ast_copy_string(tmp->chan->dialcontext, chan->macrocontext, sizeof(tmp->chan->dialcontext));
01241 else
01242 ast_copy_string(tmp->chan->dialcontext, chan->context, sizeof(tmp->chan->dialcontext));
01243 if (!ast_strlen_zero(chan->macroexten))
01244 ast_copy_string(tmp->chan->exten, chan->macroexten, sizeof(tmp->chan->exten));
01245 else
01246 ast_copy_string(tmp->chan->exten, chan->exten, sizeof(tmp->chan->exten));
01247
01248
01249 res = ast_call(tmp->chan, numsubst, 0);
01250
01251
01252 if (chan->cdr)
01253 ast_cdr_setdestchan(chan->cdr, tmp->chan->name);
01254
01255
01256 if (res) {
01257
01258 if (option_debug)
01259 ast_log(LOG_DEBUG, "ast call on peer returned %d\n", res);
01260 if (option_verbose > 2)
01261 ast_verbose(VERBOSE_PREFIX_3 "Couldn't call %s\n", numsubst);
01262 ast_hangup(tmp->chan);
01263 tmp->chan = NULL;
01264 free(tmp);
01265 continue;
01266 } else {
01267 senddialevent(chan, tmp->chan);
01268 if (option_verbose > 2)
01269 ast_verbose(VERBOSE_PREFIX_3 "Called %s\n", numsubst);
01270 if (!ast_test_flag(peerflags, OPT_ORIGINAL_CLID))
01271 ast_set_callerid(tmp->chan, S_OR(chan->macroexten, chan->exten), get_cid_name(cidname, sizeof(cidname), chan), NULL);
01272 }
01273
01274
01275
01276 ast_set_flag(tmp, DIAL_STILLGOING);
01277 tmp->next = outgoing;
01278 outgoing = tmp;
01279
01280 if (outgoing->chan->_state == AST_STATE_UP)
01281 break;
01282 }
01283
01284 if (ast_strlen_zero(args.timeout)) {
01285 to = -1;
01286 } else {
01287 to = atoi(args.timeout);
01288 if (to > 0)
01289 to *= 1000;
01290 else
01291 ast_log(LOG_WARNING, "Invalid timeout specified: '%s'\n", args.timeout);
01292 }
01293
01294 if (!outgoing) {
01295 strcpy(status, "CHANUNAVAIL");
01296 if(fulldial == num_dialed) {
01297 res = -1;
01298 goto out;
01299 }
01300 } else {
01301
01302 strcpy(status, "NOANSWER");
01303 if (ast_test_flag(outgoing, OPT_MUSICBACK)) {
01304 moh = 1;
01305 if (!ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
01306 char *original_moh = ast_strdupa(chan->musicclass);
01307 ast_string_field_set(chan, musicclass, opt_args[OPT_ARG_MUSICBACK]);
01308 ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
01309 ast_string_field_set(chan, musicclass, original_moh);
01310 } else {
01311 ast_moh_start(chan, NULL, NULL);
01312 }
01313 ast_indicate(chan, AST_CONTROL_PROGRESS);
01314 } else if (ast_test_flag(outgoing, OPT_RINGBACK)) {
01315 ast_indicate(chan, AST_CONTROL_RINGING);
01316 sentringing++;
01317 }
01318 }
01319
01320 time(&start_time);
01321 peer = wait_for_answer(chan, outgoing, &to, peerflags, &sentringing, status, sizeof(status), numbusy, numnochan, numcongestion, ast_test_flag(&opts, OPT_PRIORITY_JUMP), &result);
01322
01323
01324
01325
01326
01327
01328
01329 if (!ast_channel_datastore_remove(chan, datastore))
01330 ast_channel_datastore_free(datastore);
01331 if (!peer) {
01332 if (result) {
01333 res = result;
01334 } else if (to) {
01335 res = -1;
01336 } else {
01337 res = 0;
01338 }
01339
01340 } else {
01341 const char *number;
01342 time_t end_time, answer_time = time(NULL);
01343
01344 strcpy(status, "ANSWER");
01345
01346
01347
01348 hanguptree(outgoing, peer);
01349 outgoing = NULL;
01350
01351 if (chan->cdr)
01352 ast_cdr_setdestchan(chan->cdr, peer->name);
01353 if (peer->name)
01354 pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", peer->name);
01355
01356 number = pbx_builtin_getvar_helper(peer, "DIALEDPEERNUMBER");
01357 if (!number)
01358 number = numsubst;
01359 pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", number);
01360 if (!ast_strlen_zero(args.url) && ast_channel_supports_html(peer) ) {
01361 if (option_debug)
01362 ast_log(LOG_DEBUG, "app_dial: sendurl=%s.\n", args.url);
01363 ast_channel_sendurl( peer, args.url );
01364 }
01365 if ( (ast_test_flag(&opts, OPT_PRIVACY) || ast_test_flag(&opts, OPT_SCREENING)) && privdb_val == AST_PRIVACY_UNKNOWN) {
01366 int res2;
01367 int loopcount = 0;
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377 if (ast_test_flag(&opts, OPT_MUSICBACK) && !ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
01378 char *original_moh = ast_strdupa(chan->musicclass);
01379 ast_indicate(chan, -1);
01380 ast_string_field_set(chan, musicclass, opt_args[OPT_ARG_MUSICBACK]);
01381 ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
01382 ast_string_field_set(chan, musicclass, original_moh);
01383 } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
01384 ast_indicate(chan, AST_CONTROL_RINGING);
01385 sentringing++;
01386 }
01387
01388
01389 res2 = ast_autoservice_start(chan);
01390
01391 for (loopcount = 0; loopcount < 3; loopcount++) {
01392 if (res2 && loopcount == 0)
01393 break;
01394 if (!res2)
01395 res2 = ast_play_and_wait(peer,"priv-callpending");
01396 if (!valid_priv_reply(&opts, res2))
01397 res2 = 0;
01398
01399
01400
01401 if (!res2)
01402 res2 = ast_play_and_wait(peer,privintro);
01403 if (!valid_priv_reply(&opts, res2))
01404 res2 = 0;
01405
01406 if( !res2 ) {
01407
01408 if( ast_test_flag(&opts, OPT_PRIVACY) )
01409 res2 = ast_play_and_wait(peer,"priv-callee-options");
01410 if( ast_test_flag(&opts, OPT_SCREENING) )
01411 res2 = ast_play_and_wait(peer,"screen-callee-options");
01412 }
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429 if (valid_priv_reply(&opts, res2))
01430 break;
01431
01432 res2 = ast_play_and_wait(peer, "vm-sorry");
01433 }
01434
01435 if (ast_test_flag(&opts, OPT_MUSICBACK)) {
01436 ast_moh_stop(chan);
01437 } else if (ast_test_flag(&opts, OPT_RINGBACK)) {
01438 ast_indicate(chan, -1);
01439 sentringing=0;
01440 }
01441 ast_autoservice_stop(chan);
01442
01443 switch (res2) {
01444 case '1':
01445 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
01446 if (option_verbose > 2)
01447 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to ALLOW\n",
01448 opt_args[OPT_ARG_PRIVACY], privcid);
01449 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_ALLOW);
01450 }
01451 break;
01452 case '2':
01453 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
01454 if (option_verbose > 2)
01455 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to DENY\n",
01456 opt_args[OPT_ARG_PRIVACY], privcid);
01457 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_DENY);
01458 }
01459 ast_copy_string(status, "NOANSWER", sizeof(status));
01460 ast_hangup(peer);
01461 res=0;
01462 goto out;
01463 case '3':
01464 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
01465 if (option_verbose > 2)
01466 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to TORTURE\n",
01467 opt_args[OPT_ARG_PRIVACY], privcid);
01468 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_TORTURE);
01469 }
01470 ast_copy_string(status, "TORTURE", sizeof(status));
01471
01472 res = 0;
01473 ast_hangup(peer);
01474 goto out;
01475 case '4':
01476 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
01477 if (option_verbose > 2)
01478 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to KILL\n",
01479 opt_args[OPT_ARG_PRIVACY], privcid);
01480 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_KILL);
01481 }
01482
01483 ast_copy_string(status, "DONTCALL", sizeof(status));
01484 res = 0;
01485 ast_hangup(peer);
01486 goto out;
01487 case '5':
01488 if( ast_test_flag(&opts, OPT_PRIVACY) ) {
01489 if (option_verbose > 2)
01490 ast_verbose(VERBOSE_PREFIX_3 "--Set privacy database entry %s/%s to ALLOW\n",
01491 opt_args[OPT_ARG_PRIVACY], privcid);
01492 ast_privacy_set(opt_args[OPT_ARG_PRIVACY], privcid, AST_PRIVACY_ALLOW);
01493 ast_hangup(peer);
01494 res=0;
01495 goto out;
01496 }
01497 default:
01498
01499
01500
01501
01502 ast_log(LOG_NOTICE, "privacy: no valid response from the callee. Sending the caller to voicemail, the callee isn't responding\n");
01503 ast_hangup(peer);
01504 res=0;
01505 goto out;
01506 }
01507
01508
01509
01510
01511
01512
01513
01514 if( strncmp(privcid,"NOCALLERID",10) == 0 || ast_test_flag(&opts, OPT_SCREEN_NOINTRO) ) {
01515 ast_filedelete(privintro, NULL);
01516 if( ast_fileexists(privintro, NULL, NULL ) > 0 )
01517 ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", privintro);
01518 else if (option_verbose > 2)
01519 ast_verbose(VERBOSE_PREFIX_3 "Successfully deleted %s intro file\n", privintro);
01520 }
01521 }
01522 if (!ast_test_flag(&opts, OPT_ANNOUNCE) || ast_strlen_zero(opt_args[OPT_ARG_ANNOUNCE])) {
01523 res = 0;
01524 } else {
01525 int digit = 0;
01526
01527 res = ast_autoservice_start(chan);
01528
01529 if (!res)
01530 res = ast_streamfile(peer, opt_args[OPT_ARG_ANNOUNCE], peer->language);
01531 if (!res) {
01532 digit = ast_waitstream(peer, AST_DIGIT_ANY);
01533 }
01534
01535 res = ast_autoservice_stop(chan);
01536 if (digit > 0 && !res)
01537 res = ast_senddigit(chan, digit);
01538 else
01539 res = digit;
01540
01541 }
01542
01543 if (chan && peer && ast_test_flag(&opts, OPT_GOTO) && !ast_strlen_zero(opt_args[OPT_ARG_GOTO])) {
01544 replace_macro_delimiter(opt_args[OPT_ARG_GOTO]);
01545 ast_parseable_goto(chan, opt_args[OPT_ARG_GOTO]);
01546
01547 ast_copy_string(peer->context, chan->context, sizeof(peer->context));
01548 ast_copy_string(peer->exten, chan->exten, sizeof(peer->exten));
01549 peer->priority = chan->priority + 2;
01550 ast_pbx_start(peer);
01551 hanguptree(outgoing, NULL);
01552 if (continue_exec)
01553 *continue_exec = 1;
01554 res = 0;
01555 goto done;
01556 }
01557
01558 if (ast_test_flag(&opts, OPT_CALLEE_MACRO) && !ast_strlen_zero(opt_args[OPT_ARG_CALLEE_MACRO])) {
01559 struct ast_app *theapp;
01560 const char *macro_result;
01561
01562 res = ast_autoservice_start(chan);
01563 if (res) {
01564 ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
01565 res = -1;
01566 }
01567
01568 theapp = pbx_findapp("Macro");
01569
01570 if (theapp && !res) {
01571 replace_macro_delimiter(opt_args[OPT_ARG_CALLEE_MACRO]);
01572 res = pbx_exec(peer, theapp, opt_args[OPT_ARG_CALLEE_MACRO]);
01573 ast_log(LOG_DEBUG, "Macro exited with status %d\n", res);
01574 res = 0;
01575 } else {
01576 ast_log(LOG_ERROR, "Could not find application Macro\n");
01577 res = -1;
01578 }
01579
01580 if (ast_autoservice_stop(chan) < 0) {
01581 ast_log(LOG_ERROR, "Could not stop autoservice on calling channel\n");
01582 res = -1;
01583 }
01584
01585 if (!res && (macro_result = pbx_builtin_getvar_helper(peer, "MACRO_RESULT"))) {
01586 char *macro_transfer_dest;
01587
01588 if (!strcasecmp(macro_result, "BUSY")) {
01589 ast_copy_string(status, macro_result, sizeof(status));
01590 if (ast_opt_priority_jumping || ast_test_flag(&opts, OPT_PRIORITY_JUMP)) {
01591 if (!ast_goto_if_exists(chan, NULL, NULL, chan->priority + 101)) {
01592 ast_set_flag(peerflags, OPT_GO_ON);
01593 }
01594 } else
01595 ast_set_flag(peerflags, OPT_GO_ON);
01596 res = -1;
01597 } else if (!strcasecmp(macro_result, "CONGESTION") || !strcasecmp(macro_result, "CHANUNAVAIL")) {
01598 ast_copy_string(status, macro_result, sizeof(status));
01599 ast_set_flag(peerflags, OPT_GO_ON);
01600 res = -1;
01601 } else if (!strcasecmp(macro_result, "CONTINUE")) {
01602
01603
01604
01605
01606 ast_set_flag(peerflags, OPT_GO_ON);
01607 res = -1;
01608 } else if (!strcasecmp(macro_result, "ABORT")) {
01609
01610 res = -1;
01611 } else if (!strncasecmp(macro_result, "GOTO:", 5) && (macro_transfer_dest = ast_strdupa(macro_result + 5))) {
01612 res = -1;
01613
01614 if (strchr(macro_transfer_dest, '^')) {
01615 replace_macro_delimiter(macro_transfer_dest);
01616 if (!ast_parseable_goto(chan, macro_transfer_dest))
01617 ast_set_flag(peerflags, OPT_GO_ON);
01618
01619 }
01620 }
01621 }
01622 }
01623
01624 if (!res) {
01625 if (calldurationlimit > 0) {
01626 peer->whentohangup = time(NULL) + calldurationlimit;
01627 }
01628 if (!ast_strlen_zero(dtmfcalled)) {
01629 if (option_verbose > 2)
01630 ast_verbose(VERBOSE_PREFIX_3 "Sending DTMF '%s' to the called party.\n", dtmfcalled);
01631 res = ast_dtmf_stream(peer,chan,dtmfcalled,250);
01632 }
01633 if (!ast_strlen_zero(dtmfcalling)) {
01634 if (option_verbose > 2)
01635 ast_verbose(VERBOSE_PREFIX_3 "Sending DTMF '%s' to the calling party.\n", dtmfcalling);
01636 res = ast_dtmf_stream(chan,peer,dtmfcalling,250);
01637 }
01638 }
01639
01640 if (!res) {
01641 struct ast_bridge_config config;
01642
01643 memset(&config,0,sizeof(struct ast_bridge_config));
01644 if (play_to_caller)
01645 ast_set_flag(&(config.features_caller), AST_FEATURE_PLAY_WARNING);
01646 if (play_to_callee)
01647 ast_set_flag(&(config.features_callee), AST_FEATURE_PLAY_WARNING);
01648 if (ast_test_flag(peerflags, OPT_CALLEE_TRANSFER))
01649 ast_set_flag(&(config.features_callee), AST_FEATURE_REDIRECT);
01650 if (ast_test_flag(peerflags, OPT_CALLER_TRANSFER))
01651 ast_set_flag(&(config.features_caller), AST_FEATURE_REDIRECT);
01652 if (ast_test_flag(peerflags, OPT_CALLEE_HANGUP))
01653 ast_set_flag(&(config.features_callee), AST_FEATURE_DISCONNECT);
01654 if (ast_test_flag(peerflags, OPT_CALLER_HANGUP))
01655 ast_set_flag(&(config.features_caller), AST_FEATURE_DISCONNECT);
01656 if (ast_test_flag(peerflags, OPT_CALLEE_MONITOR))
01657 ast_set_flag(&(config.features_callee), AST_FEATURE_AUTOMON);
01658 if (ast_test_flag(peerflags, OPT_CALLER_MONITOR))
01659 ast_set_flag(&(config.features_caller), AST_FEATURE_AUTOMON);
01660 if (ast_test_flag(peerflags, OPT_CALLEE_PARK))
01661 ast_set_flag(&(config.features_callee), AST_FEATURE_PARKCALL);
01662 if (ast_test_flag(peerflags, OPT_CALLER_PARK))
01663 ast_set_flag(&(config.features_caller), AST_FEATURE_PARKCALL);
01664
01665 config.timelimit = timelimit;
01666 config.play_warning = play_warning;
01667 config.warning_freq = warning_freq;
01668 config.warning_sound = warning_sound;
01669 config.end_sound = end_sound;
01670 config.start_sound = start_sound;
01671 if (moh) {
01672 moh = 0;
01673 ast_moh_stop(chan);
01674 } else if (sentringing) {
01675 sentringing = 0;
01676 ast_indicate(chan, -1);
01677 }
01678
01679 ast_deactivate_generator(chan);
01680
01681 res = ast_channel_make_compatible(chan, peer);
01682 if (res < 0) {
01683 ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", chan->name, peer->name);
01684 ast_hangup(peer);
01685 res = -1;
01686 goto done;
01687 }
01688 if (opermode && (!strncmp(chan->name,"Zap",3)) &&
01689 (!strncmp(peer->name,"Zap",3)))
01690 {
01691 struct oprmode oprmode;
01692
01693 oprmode.peer = peer;
01694 oprmode.mode = opermode;
01695
01696 ast_channel_setoption(chan,
01697 AST_OPTION_OPRMODE,&oprmode,sizeof(struct oprmode),0);
01698 }
01699 res = ast_bridge_call(chan,peer,&config);
01700 time(&end_time);
01701 {
01702 char toast[80];
01703 snprintf(toast, sizeof(toast), "%ld", (long)(end_time - answer_time));
01704 pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", toast);
01705 }
01706 } else {
01707 time(&end_time);
01708 res = -1;
01709 }
01710 {
01711 char toast[80];
01712 snprintf(toast, sizeof(toast), "%ld", (long)(end_time - start_time));
01713 pbx_builtin_setvar_helper(chan, "DIALEDTIME", toast);
01714 }
01715
01716 if (res != AST_PBX_NO_HANGUP_PEER) {
01717 if (!chan->_softhangup)
01718 chan->hangupcause = peer->hangupcause;
01719 ast_hangup(peer);
01720 }
01721 }
01722 out:
01723 if (moh) {
01724 moh = 0;
01725 ast_moh_stop(chan);
01726 } else if (sentringing) {
01727 sentringing = 0;
01728 ast_indicate(chan, -1);
01729 }
01730 ast_rtp_early_bridge(chan, NULL);
01731 hanguptree(outgoing, NULL);
01732 pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
01733 if (option_debug)
01734 ast_log(LOG_DEBUG, "Exiting with DIALSTATUS=%s (HANGUPCAUSE=%d)\n", status, chan->hangupcause);
01735
01736 if ((ast_test_flag(peerflags, OPT_GO_ON)) && (!chan->_softhangup) && (res != AST_PBX_KEEPALIVE)) {
01737 if (calldurationlimit)
01738 chan->whentohangup = 0;
01739 res = 0;
01740 }
01741
01742 done:
01743 ast_module_user_remove(u);
01744 return res;
01745 }
01746
01747 static int dial_exec(struct ast_channel *chan, void *data)
01748 {
01749 struct ast_flags peerflags;
01750
01751 memset(&peerflags, 0, sizeof(peerflags));
01752
01753 return dial_exec_full(chan, data, &peerflags, NULL);
01754 }
01755
01756 static int retrydial_exec(struct ast_channel *chan, void *data)
01757 {
01758 char *announce = NULL, *dialdata = NULL;
01759 const char *context = NULL;
01760 int sleep = 0, loops = 0, res = -1;
01761 struct ast_module_user *u;
01762 struct ast_flags peerflags;
01763
01764 if (ast_strlen_zero(data)) {
01765 ast_log(LOG_WARNING, "RetryDial requires an argument!\n");
01766 return -1;
01767 }
01768
01769 u = ast_module_user_add(chan);
01770
01771 announce = ast_strdupa(data);
01772
01773 memset(&peerflags, 0, sizeof(peerflags));
01774
01775 if ((dialdata = strchr(announce, '|'))) {
01776 *dialdata++ = '\0';
01777 if (sscanf(dialdata, "%d", &sleep) == 1) {
01778 sleep *= 1000;
01779 } else {
01780 ast_log(LOG_ERROR, "%s requires the numerical argument <sleep>\n",rapp);
01781 goto done;
01782 }
01783 if ((dialdata = strchr(dialdata, '|'))) {
01784 *dialdata++ = '\0';
01785 if (sscanf(dialdata, "%d", &loops) != 1) {
01786 ast_log(LOG_ERROR, "%s requires the numerical argument <loops>\n",rapp);
01787 goto done;
01788 }
01789 }
01790 }
01791
01792 if ((dialdata = strchr(dialdata, '|'))) {
01793 *dialdata++ = '\0';
01794 } else {
01795 ast_log(LOG_ERROR, "%s requires more arguments\n",rapp);
01796 goto done;
01797 }
01798
01799 if (sleep < 1000)
01800 sleep = 10000;
01801
01802 if (!loops)
01803 loops = -1;
01804
01805 context = pbx_builtin_getvar_helper(chan, "EXITCONTEXT");
01806
01807 res = 0;
01808 while (loops) {
01809 int continue_exec;
01810
01811 chan->data = "Retrying";
01812 if (ast_test_flag(chan, AST_FLAG_MOH))
01813 ast_moh_stop(chan);
01814
01815 res = dial_exec_full(chan, dialdata, &peerflags, &continue_exec);
01816 if (continue_exec)
01817 break;
01818
01819 if (res == 0) {
01820 if (ast_test_flag(&peerflags, OPT_DTMF_EXIT)) {
01821 if (!ast_strlen_zero(announce)) {
01822 if (ast_fileexists(announce, NULL, chan->language) > 0) {
01823 if(!(res = ast_streamfile(chan, announce, chan->language)))
01824 ast_waitstream(chan, AST_DIGIT_ANY);
01825 } else
01826 ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", announce);
01827 }
01828 if (!res && sleep) {
01829 if (!ast_test_flag(chan, AST_FLAG_MOH))
01830 ast_moh_start(chan, NULL, NULL);
01831 res = ast_waitfordigit(chan, sleep);
01832 }
01833 } else {
01834 if (!ast_strlen_zero(announce)) {
01835 if (ast_fileexists(announce, NULL, chan->language) > 0) {
01836 if (!(res = ast_streamfile(chan, announce, chan->language)))
01837 res = ast_waitstream(chan, "");
01838 } else
01839 ast_log(LOG_WARNING, "Announce file \"%s\" specified in Retrydial does not exist\n", announce);
01840 }
01841 if (sleep) {
01842 if (!ast_test_flag(chan, AST_FLAG_MOH))
01843 ast_moh_start(chan, NULL, NULL);
01844 if (!res)
01845 res = ast_waitfordigit(chan, sleep);
01846 }
01847 }
01848 }
01849
01850 if (res < 0)
01851 break;
01852 else if (res > 0) {
01853 if (onedigit_goto(chan, context, (char) res, 1)) {
01854 res = 0;
01855 break;
01856 }
01857 }
01858 loops--;
01859 }
01860 if (loops == 0)
01861 res = 0;
01862 else if (res == 1)
01863 res = 0;
01864
01865 if (ast_test_flag(chan, AST_FLAG_MOH))
01866 ast_moh_stop(chan);
01867 done:
01868 ast_module_user_remove(u);
01869 return res;
01870 }
01871
01872 static int unload_module(void)
01873 {
01874 int res;
01875
01876 res = ast_unregister_application(app);
01877 res |= ast_unregister_application(rapp);
01878
01879 ast_module_user_hangup_all();
01880
01881 return res;
01882 }
01883
01884 static int load_module(void)
01885 {
01886 int res;
01887
01888 res = ast_register_application(app, dial_exec, synopsis, descrip);
01889 res |= ast_register_application(rapp, retrydial_exec, rsynopsis, rdescrip);
01890
01891 return res;
01892 }
01893
01894 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Dialing Application");