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