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