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