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