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