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