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