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