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