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