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