2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 1999 - 2006, Digium, Inc.
6 * Mark Spencer <markster@digium.com>
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
21 * \brief dial() & retrydial() - Trivial application to dial a channel and send an URL on answer
23 * \author Mark Spencer <markster@digium.com>
25 * \ingroup applications
30 ASTERISK_FILE_VERSION(__FILE__
, "$Revision$")
39 #include <sys/signal.h>
41 #include <netinet/in.h>
43 #include "asterisk/lock.h"
44 #include "asterisk/file.h"
45 #include "asterisk/logger.h"
46 #include "asterisk/channel.h"
47 #include "asterisk/pbx.h"
48 #include "asterisk/options.h"
49 #include "asterisk/module.h"
50 #include "asterisk/translate.h"
51 #include "asterisk/say.h"
52 #include "asterisk/config.h"
53 #include "asterisk/features.h"
54 #include "asterisk/musiconhold.h"
55 #include "asterisk/callerid.h"
56 #include "asterisk/utils.h"
57 #include "asterisk/app.h"
58 #include "asterisk/causes.h"
59 #include "asterisk/rtp.h"
60 #include "asterisk/manager.h"
61 #include "asterisk/privacy.h"
62 #include "asterisk/stringfields.h"
64 static char *app
= "Dial";
66 static char *synopsis
= "Place a call and connect to the current channel";
68 static char *descrip
=
69 " Dial(Technology/resource[&Tech2/resource2...][|timeout][|options][|URL]):\n"
70 "This application will place calls to one or more specified channels. As soon\n"
71 "as one of the requested channels answers, the originating channel will be\n"
72 "answered, if it has not already been answered. These two channels will then\n"
73 "be active in a bridged call. All other channels that were requested will then\n"
75 " Unless there is a timeout specified, the Dial application will wait\n"
76 "indefinitely until one of the called channels answers, the user hangs up, or\n"
77 "if all of the called channels are busy or unavailable. Dialplan executing will\n"
78 "continue if no requested channels can be called, or if the timeout expires.\n\n"
79 " This application sets the following channel variables upon completion:\n"
80 " DIALEDTIME - This is the time from dialing a channel until when it\n"
82 " ANSWEREDTIME - This is the amount of time for actual call.\n"
83 " DIALSTATUS - This is the status of the call:\n"
84 " CHANUNAVAIL | CONGESTION | NOANSWER | BUSY | ANSWER | CANCEL\n"
85 " DONTCALL | TORTURE | INVALIDARGS\n"
86 " For the Privacy and Screening Modes, the DIALSTATUS variable will be set to\n"
87 "DONTCALL if the called party chooses to send the calling party to the 'Go Away'\n"
88 "script. The DIALSTATUS variable will be set to TORTURE if the called party\n"
89 "wants to send the caller to the 'torture' script.\n"
90 " This application will report normal termination if the originating channel\n"
91 "hangs up, or if the call is bridged and either of the parties in the bridge\n"
93 " The optional URL will be sent to the called party if the channel supports it.\n"
94 " If the OUTBOUND_GROUP variable is set, all peer channels created by this\n"
95 "application will be put into that group (as in Set(GROUP()=...).\n"
96 " If the OUTBOUND_GROUP_ONCE variable is set, all peer channels created by this\n"
97 "application will be put into that group (as in Set(GROUP()=...). Unlike OUTBOUND_GROUP,\n"
98 "however, the variable will be unset after use.\n\n"
100 " A(x) - Play an announcement to the called party, using 'x' as the file.\n"
101 " C - Reset the CDR for this call.\n"
102 " d - Allow the calling user to dial a 1 digit extension while waiting for\n"
103 " a call to be answered. Exit to that extension if it exists in the\n"
104 " current context, or the context defined in the EXITCONTEXT variable,\n"
106 " D([called][:calling]) - Send the specified DTMF strings *after* the called\n"
107 " party has answered, but before the call gets bridged. The 'called'\n"
108 " DTMF string is sent to the called party, and the 'calling' DTMF\n"
109 " string is sent to the calling party. Both parameters can be used\n"
111 " f - Force the callerid of the *calling* channel to be set as the\n"
112 " extension associated with the channel using a dialplan 'hint'.\n"
113 " For example, some PSTNs do not allow CallerID to be set to anything\n"
114 " other than the number assigned to the caller.\n"
115 " g - Proceed with dialplan execution at the current extension if the\n"
116 " destination channel hangs up.\n"
117 " G(context^exten^pri) - If the call is answered, transfer the calling party to\n"
118 " the specified priority and the called party to the specified priority+1.\n"
119 " Optionally, an extension, or extension and context may be specified. \n"
120 " Otherwise, the current extension is used. You cannot use any additional\n"
121 " action post answer options in conjunction with this option.\n"
122 " h - Allow the called party to hang up by sending the '*' DTMF digit.\n"
123 " H - Allow the calling party to hang up by hitting the '*' DTMF digit.\n"
124 " i - Asterisk will ignore any forwarding requests it may receive on this\n"
126 " j - Jump to priority n+101 if all of the requested channels were busy.\n"
127 " k - Allow the called party to enable parking of the call by sending\n"
128 " the DTMF sequence defined for call parking in features.conf.\n"
129 " K - Allow the calling party to enable parking of the call by sending\n"
130 " the DTMF sequence defined for call parking in features.conf.\n"
131 " L(x[:y][:z]) - Limit the call to 'x' ms. Play a warning when 'y' ms are\n"
132 " left. Repeat the warning every 'z' ms. The following special\n"
133 " variables can be used with this option:\n"
134 " * LIMIT_PLAYAUDIO_CALLER yes|no (default yes)\n"
135 " Play sounds to the caller.\n"
136 " * LIMIT_PLAYAUDIO_CALLEE yes|no\n"
137 " Play sounds to the callee.\n"
138 " * LIMIT_TIMEOUT_FILE File to play when time is up.\n"
139 " * LIMIT_CONNECT_FILE File to play when call begins.\n"
140 " * LIMIT_WARNING_FILE File to play as warning if 'y' is defined.\n"
141 " The default is to say the time remaining.\n"
142 " m([class]) - Provide hold music to the calling party until a requested\n"
143 " channel answers. A specific MusicOnHold class can be\n"
145 " M(x[^arg]) - Execute the Macro for the *called* channel before connecting\n"
146 " to the calling channel. Arguments can be specified to the Macro\n"
147 " using '^' as a delimeter. The Macro can set the variable\n"
148 " MACRO_RESULT to specify the following actions after the Macro is\n"
149 " finished executing.\n"
150 " * ABORT Hangup both legs of the call.\n"
151 " * CONGESTION Behave as if line congestion was encountered.\n"
152 " * BUSY Behave as if a busy signal was encountered. This will also\n"
153 " have the application jump to priority n+101 if the\n"
154 " 'j' option is set.\n"
155 " * CONTINUE Hangup the called party and allow the calling party\n"
156 " to continue dialplan execution at the next priority.\n"
157 " * GOTO:<context>^<exten>^<priority> - Transfer the call to the\n"
158 " specified priority. Optionally, an extension, or\n"
159 " extension and priority can be specified.\n"
160 " You cannot use any additional action post answer options in conjunction\n"
161 " with this option. Also, pbx services are not run on the peer (called) channel,\n"
162 " so you will not be able to set timeouts via the TIMEOUT() function in this macro.\n"
163 " n - This option is a modifier for the screen/privacy mode. It specifies\n"
164 " that no introductions are to be saved in the priv-callerintros\n"
166 " N - This option is a modifier for the screen/privacy mode. It specifies\n"
167 " that if callerID is present, do not screen the call.\n"
168 " o - Specify that the CallerID that was present on the *calling* channel\n"
169 " be set as the CallerID on the *called* channel. This was the\n"
170 " behavior of Asterisk 1.0 and earlier.\n"
171 " O([x]) - \"Operator Services\" mode (Zaptel channel to Zaptel channel\n"
172 " only, if specified on non-Zaptel interface, it will be ignored).\n"
173 " When the destination answers (presumably an operator services\n"
174 " station), the originator no longer has control of their line.\n"
175 " They may hang up, but the switch will not release their line\n"
176 " until the destination party hangs up (the operator). Specified\n"
177 " without an arg, or with 1 as an arg, the originator hanging up\n"
178 " will cause the phone to ring back immediately. With a 2 specified,\n"
179 " when the \"operator\" flashes the trunk, it will ring their phone\n"
181 " p - This option enables screening mode. This is basically Privacy mode\n"
183 " P([x]) - Enable privacy mode. Use 'x' as the family/key in the database if\n"
184 " it is provided. The current extension is used if a database\n"
185 " family/key is not specified.\n"
186 " r - Indicate ringing to the calling party. Pass no audio to the calling\n"
187 " party until the called channel has answered.\n"
188 " S(x) - Hang up the call after 'x' seconds *after* the called party has\n"
189 " answered the call.\n"
190 " t - Allow the called party to transfer the calling party by sending the\n"
191 " DTMF sequence defined in features.conf.\n"
192 " T - Allow the calling party to transfer the called party by sending the\n"
193 " DTMF sequence defined in features.conf.\n"
194 " w - Allow the called party to enable recording of the call by sending\n"
195 " the DTMF sequence defined for one-touch recording in features.conf.\n"
196 " W - Allow the calling party to enable recording of the call by sending\n"
197 " the DTMF sequence defined for one-touch recording in features.conf.\n";
199 /* RetryDial App by Anthony Minessale II <anthmct@yahoo.com> Jan/2005 */
200 static char *rapp
= "RetryDial";
201 static char *rsynopsis
= "Place a call, retrying on failure allowing optional exit extension.";
202 static char *rdescrip
=
203 " RetryDial(announce|sleep|retries|dialargs): This application will attempt to\n"
204 "place a call using the normal Dial application. If no channel can be reached,\n"
205 "the 'announce' file will be played. Then, it will wait 'sleep' number of\n"
206 "seconds before retying the call. After 'retires' number of attempts, the\n"
207 "calling channel will continue at the next priority in the dialplan. If the\n"
208 "'retries' setting is set to 0, this application will retry endlessly.\n"
209 " While waiting to retry a call, a 1 digit extension may be dialed. If that\n"
210 "extension exists in either the context defined in ${EXITCONTEXT} or the current\n"
211 "one, The call will jump to that extension immediately.\n"
212 " The 'dialargs' are specified in the same format that arguments are provided\n"
213 "to the Dial application.\n";
216 OPT_ANNOUNCE
= (1 << 0),
217 OPT_RESETCDR
= (1 << 1),
218 OPT_DTMF_EXIT
= (1 << 2),
219 OPT_SENDDTMF
= (1 << 3),
220 OPT_FORCECLID
= (1 << 4),
221 OPT_GO_ON
= (1 << 5),
222 OPT_CALLEE_HANGUP
= (1 << 6),
223 OPT_CALLER_HANGUP
= (1 << 7),
224 OPT_PRIORITY_JUMP
= (1 << 8),
225 OPT_DURATION_LIMIT
= (1 << 9),
226 OPT_MUSICBACK
= (1 << 10),
227 OPT_CALLEE_MACRO
= (1 << 11),
228 OPT_SCREEN_NOINTRO
= (1 << 12),
229 OPT_SCREEN_NOCLID
= (1 << 13),
230 OPT_ORIGINAL_CLID
= (1 << 14),
231 OPT_SCREENING
= (1 << 15),
232 OPT_PRIVACY
= (1 << 16),
233 OPT_RINGBACK
= (1 << 17),
234 OPT_DURATION_STOP
= (1 << 18),
235 OPT_CALLEE_TRANSFER
= (1 << 19),
236 OPT_CALLER_TRANSFER
= (1 << 20),
237 OPT_CALLEE_MONITOR
= (1 << 21),
238 OPT_CALLER_MONITOR
= (1 << 22),
239 OPT_GOTO
= (1 << 23),
240 OPT_OPERMODE
= (1 << 24),
241 OPT_CALLEE_PARK
= (1 << 25),
242 OPT_CALLER_PARK
= (1 << 26),
243 OPT_IGNORE_FORWARDING
= (1 << 27),
244 } dial_exec_option_flags
;
246 #define DIAL_STILLGOING (1 << 30)
247 #define DIAL_NOFORWARDHTML (1 << 31)
250 OPT_ARG_ANNOUNCE
= 0,
253 OPT_ARG_DURATION_LIMIT
,
255 OPT_ARG_CALLEE_MACRO
,
257 OPT_ARG_DURATION_STOP
,
259 /* note: this entry _MUST_ be the last one in the enum */
261 } dial_exec_option_args
;
263 AST_APP_OPTIONS(dial_exec_options
, {
264 AST_APP_OPTION_ARG('A', OPT_ANNOUNCE
, OPT_ARG_ANNOUNCE
),
265 AST_APP_OPTION('C', OPT_RESETCDR
),
266 AST_APP_OPTION('d', OPT_DTMF_EXIT
),
267 AST_APP_OPTION_ARG('D', OPT_SENDDTMF
, OPT_ARG_SENDDTMF
),
268 AST_APP_OPTION('f', OPT_FORCECLID
),
269 AST_APP_OPTION('g', OPT_GO_ON
),
270 AST_APP_OPTION_ARG('G', OPT_GOTO
, OPT_ARG_GOTO
),
271 AST_APP_OPTION('h', OPT_CALLEE_HANGUP
),
272 AST_APP_OPTION('H', OPT_CALLER_HANGUP
),
273 AST_APP_OPTION('i', OPT_IGNORE_FORWARDING
),
274 AST_APP_OPTION('j', OPT_PRIORITY_JUMP
),
275 AST_APP_OPTION('k', OPT_CALLEE_PARK
),
276 AST_APP_OPTION('K', OPT_CALLER_PARK
),
277 AST_APP_OPTION_ARG('L', OPT_DURATION_LIMIT
, OPT_ARG_DURATION_LIMIT
),
278 AST_APP_OPTION_ARG('m', OPT_MUSICBACK
, OPT_ARG_MUSICBACK
),
279 AST_APP_OPTION_ARG('M', OPT_CALLEE_MACRO
, OPT_ARG_CALLEE_MACRO
),
280 AST_APP_OPTION('n', OPT_SCREEN_NOINTRO
),
281 AST_APP_OPTION('N', OPT_SCREEN_NOCLID
),
282 AST_APP_OPTION('o', OPT_ORIGINAL_CLID
),
283 AST_APP_OPTION_ARG('O', OPT_OPERMODE
,OPT_ARG_OPERMODE
),
284 AST_APP_OPTION('p', OPT_SCREENING
),
285 AST_APP_OPTION_ARG('P', OPT_PRIVACY
, OPT_ARG_PRIVACY
),
286 AST_APP_OPTION('r', OPT_RINGBACK
),
287 AST_APP_OPTION_ARG('S', OPT_DURATION_STOP
, OPT_ARG_DURATION_STOP
),
288 AST_APP_OPTION('t', OPT_CALLEE_TRANSFER
),
289 AST_APP_OPTION('T', OPT_CALLER_TRANSFER
),
290 AST_APP_OPTION('w', OPT_CALLEE_MONITOR
),
291 AST_APP_OPTION('W', OPT_CALLER_MONITOR
),
294 #define CAN_EARLY_BRIDGE(flags) (!ast_test_flag(flags, OPT_CALLEE_HANGUP | \
295 OPT_CALLER_HANGUP | OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER | \
296 OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR | OPT_CALLEE_PARK | OPT_CALLER_PARK))
298 /* We define a custom "local user" structure because we
299 use it not only for keeping track of what is in use but
300 also for keeping track of who we're dialing. */
302 struct dial_localuser
{
303 struct ast_channel
*chan
;
306 struct dial_localuser
*next
;
310 static void hanguptree(struct dial_localuser
*outgoing
, struct ast_channel
*exception
)
312 /* Hang up a tree of stuff */
313 struct dial_localuser
*oo
;
315 /* Hangup any existing lines we have open */
316 if (outgoing
->chan
&& (outgoing
->chan
!= exception
))
317 ast_hangup(outgoing
->chan
);
319 outgoing
=outgoing
->next
;
324 #define AST_MAX_FORWARDS 8
326 #define AST_MAX_WATCHERS 256
328 #define HANDLE_CAUSE(cause, chan) do { \
330 case AST_CAUSE_BUSY: \
332 ast_cdr_busy(chan->cdr); \
335 case AST_CAUSE_CONGESTION: \
337 ast_cdr_failed(chan->cdr); \
340 case AST_CAUSE_UNREGISTERED: \
342 ast_cdr_failed(chan->cdr); \
345 case AST_CAUSE_NORMAL_CLEARING: \
354 static int onedigit_goto(struct ast_channel
*chan
, const char *context
, char exten
, int pri
)
356 char rexten
[2] = { exten
, '\0' };
359 if (!ast_goto_if_exists(chan
, context
, rexten
, pri
))
362 if (!ast_goto_if_exists(chan
, chan
->context
, rexten
, pri
))
364 else if (!ast_strlen_zero(chan
->macrocontext
)) {
365 if (!ast_goto_if_exists(chan
, chan
->macrocontext
, rexten
, pri
))
373 static const char *get_cid_name(char *name
, int namelen
, struct ast_channel
*chan
)
375 const char *context
= S_OR(chan
->macrocontext
, chan
->context
);
376 const char *exten
= S_OR(chan
->macroexten
, chan
->exten
);
378 return ast_get_hint(NULL
, 0, name
, namelen
, chan
, context
, exten
) ? name
: "";
381 static void senddialevent(struct ast_channel
*src
, struct ast_channel
*dst
)
383 /* XXX do we need also CallerIDnum ? */
384 manager_event(EVENT_FLAG_CALL
, "Dial",
386 "Destination: %s\r\n"
388 "CallerIDName: %s\r\n"
389 "SrcUniqueID: %s\r\n"
390 "DestUniqueID: %s\r\n",
391 src
->name
, dst
->name
, S_OR(src
->cid
.cid_num
, "<unknown>"),
392 S_OR(src
->cid
.cid_name
, "<unknown>"), src
->uniqueid
,
396 static struct ast_channel
*wait_for_answer(struct ast_channel
*in
, struct dial_localuser
*outgoing
, int *to
, struct ast_flags
*peerflags
, int *sentringing
, char *status
, size_t statussize
, int busystart
, int nochanstart
, int congestionstart
, int priority_jump
, int *result
)
398 int numbusy
= busystart
;
399 int numcongestion
= congestionstart
;
400 int numnochan
= nochanstart
;
401 int prestart
= busystart
+ congestionstart
+ nochanstart
;
403 struct ast_channel
*peer
= NULL
;
404 /* single is set if only one destination is enabled */
405 int single
= outgoing
&& !outgoing
->next
&& !ast_test_flag(outgoing
, OPT_MUSICBACK
| OPT_RINGBACK
);
408 /* Turn off hold music, etc */
409 ast_deactivate_generator(in
);
410 /* If we are calling a single channel, make them compatible for in-band tone purpose */
411 ast_channel_make_compatible(outgoing
->chan
, in
);
415 while (*to
&& !peer
) {
416 struct dial_localuser
*o
;
417 int pos
= 0; /* how many channels do we handle */
418 int numlines
= prestart
;
419 struct ast_channel
*winner
;
420 struct ast_channel
*watchers
[AST_MAX_WATCHERS
];
422 watchers
[pos
++] = in
;
423 for (o
= outgoing
; o
; o
= o
->next
) {
424 /* Keep track of important channels */
425 if (ast_test_flag(o
, DIAL_STILLGOING
) && o
->chan
)
426 watchers
[pos
++] = o
->chan
;
429 if (pos
== 1) { /* only the input channel is available */
430 if (numlines
== (numbusy
+ numcongestion
+ numnochan
)) {
431 if (option_verbose
> 2)
432 ast_verbose( VERBOSE_PREFIX_2
"Everyone is busy/congested at this time (%d:%d/%d/%d)\n", numlines
, numbusy
, numcongestion
, numnochan
);
434 strcpy(status
, "BUSY");
435 else if (numcongestion
)
436 strcpy(status
, "CONGESTION");
438 strcpy(status
, "CHANUNAVAIL");
439 if (ast_opt_priority_jumping
|| priority_jump
)
440 ast_goto_if_exists(in
, in
->context
, in
->exten
, in
->priority
+ 101);
442 if (option_verbose
> 2)
443 ast_verbose(VERBOSE_PREFIX_3
"No one is available to answer at this time (%d:%d/%d/%d)\n", numlines
, numbusy
, numcongestion
, numnochan
);
448 winner
= ast_waitfor_n(watchers
, pos
, to
);
449 for (o
= outgoing
; o
; o
= o
->next
) {
451 struct ast_channel
*c
= o
->chan
;
455 if (ast_test_flag(o
, DIAL_STILLGOING
) && c
->_state
== AST_STATE_UP
) {
457 if (option_verbose
> 2)
458 ast_verbose(VERBOSE_PREFIX_3
"%s answered %s\n", c
->name
, in
->name
);
460 ast_copy_flags(peerflags
, o
,
461 OPT_CALLEE_TRANSFER
| OPT_CALLER_TRANSFER
|
462 OPT_CALLEE_HANGUP
| OPT_CALLER_HANGUP
|
463 OPT_CALLEE_MONITOR
| OPT_CALLER_MONITOR
|
464 OPT_CALLEE_PARK
| OPT_CALLER_PARK
|
466 ast_copy_string(c
->dialcontext
, "", sizeof(c
->dialcontext
));
467 ast_copy_string(c
->exten
, "", sizeof(c
->exten
));
473 if (!ast_strlen_zero(c
->call_forward
)) {
479 ast_copy_string(tmpchan
, c
->call_forward
, sizeof(tmpchan
));
480 if ((stuff
= strchr(tmpchan
, '/'))) {
484 const char *forward_context
= pbx_builtin_getvar_helper(c
, "FORWARD_CONTEXT");
485 snprintf(tmpchan
, sizeof(tmpchan
), "%s@%s", c
->call_forward
, forward_context
? forward_context
: c
->context
);
489 /* Before processing channel, go ahead and check for forwarding */
491 if (o
->forwards
< AST_MAX_FORWARDS
) {
492 if (option_verbose
> 2)
493 ast_verbose(VERBOSE_PREFIX_3
"Now forwarding %s to '%s/%s' (thanks to %s)\n", in
->name
, tech
, stuff
, c
->name
);
494 /* If we have been told to ignore forwards, just set this channel to null and continue processing extensions normally */
495 if (ast_test_flag(peerflags
, OPT_IGNORE_FORWARDING
)) {
496 if (option_verbose
> 2)
497 ast_verbose(VERBOSE_PREFIX_3
"Forwarding %s to '%s/%s' prevented.\n", in
->name
, tech
, stuff
);
499 cause
= AST_CAUSE_BUSY
;
501 /* Setup parameters */
502 if ((c
= o
->chan
= ast_request(tech
, in
->nativeformats
, stuff
, &cause
))) {
504 ast_channel_make_compatible(o
->chan
, in
);
505 ast_channel_inherit_variables(in
, o
->chan
);
507 ast_log(LOG_NOTICE
, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech
, stuff
, cause
);
510 if (option_verbose
> 2)
511 ast_verbose(VERBOSE_PREFIX_3
"Too many forwards from %s\n", c
->name
);
512 cause
= AST_CAUSE_CONGESTION
;
516 ast_clear_flag(o
, DIAL_STILLGOING
);
517 HANDLE_CAUSE(cause
, in
);
519 ast_rtp_make_compatible(c
, in
, single
);
521 free(c
->cid
.cid_num
);
522 c
->cid
.cid_num
= NULL
;
524 free(c
->cid
.cid_name
);
525 c
->cid
.cid_name
= NULL
;
527 if (ast_test_flag(o
, OPT_FORCECLID
)) {
528 c
->cid
.cid_num
= ast_strdup(S_OR(in
->macroexten
, in
->exten
));
529 ast_string_field_set(c
, accountcode
, winner
->accountcode
);
530 c
->cdrflags
= winner
->cdrflags
;
532 c
->cid
.cid_num
= ast_strdup(in
->cid
.cid_num
);
533 c
->cid
.cid_name
= ast_strdup(in
->cid
.cid_name
);
534 ast_string_field_set(c
, accountcode
, in
->accountcode
);
535 c
->cdrflags
= in
->cdrflags
;
538 if (in
->cid
.cid_ani
) {
540 free(c
->cid
.cid_ani
);
541 c
->cid
.cid_ani
= ast_strdup(in
->cid
.cid_ani
);
543 if (c
->cid
.cid_rdnis
)
544 free(c
->cid
.cid_rdnis
);
545 c
->cid
.cid_rdnis
= ast_strdup(S_OR(in
->macroexten
, in
->exten
));
546 if (ast_call(c
, tmpchan
, 0)) {
547 ast_log(LOG_NOTICE
, "Failed to dial on local channel for call forward to '%s'\n", tmpchan
);
548 ast_clear_flag(o
, DIAL_STILLGOING
);
553 senddialevent(in
, c
);
554 /* After calling, set callerid to extension */
555 if (!ast_test_flag(peerflags
, OPT_ORIGINAL_CLID
)) {
556 char cidname
[AST_MAX_EXTENSION
] = "";
557 ast_set_callerid(c
, S_OR(in
->macroexten
, in
->exten
), get_cid_name(cidname
, sizeof(cidname
), in
), NULL
);
561 /* Hangup the original channel now, in case we needed it */
565 f
= ast_read(winner
);
567 in
->hangupcause
= c
->hangupcause
;
570 ast_clear_flag(o
, DIAL_STILLGOING
);
571 HANDLE_CAUSE(in
->hangupcause
, in
);
574 if (f
->frametype
== AST_FRAME_CONTROL
) {
575 switch(f
->subclass
) {
576 case AST_CONTROL_ANSWER
:
577 /* This is our guy if someone answered. */
579 if (option_verbose
> 2)
580 ast_verbose( VERBOSE_PREFIX_3
"%s answered %s\n", c
->name
, in
->name
);
582 ast_copy_flags(peerflags
, o
,
583 OPT_CALLEE_TRANSFER
| OPT_CALLER_TRANSFER
|
584 OPT_CALLEE_HANGUP
| OPT_CALLER_HANGUP
|
585 OPT_CALLEE_MONITOR
| OPT_CALLER_MONITOR
|
586 OPT_CALLEE_PARK
| OPT_CALLER_PARK
|
588 ast_copy_string(c
->dialcontext
, "", sizeof(c
->dialcontext
));
589 ast_copy_string(c
->exten
, "", sizeof(c
->exten
));
590 /* Setup RTP early bridge if appropriate */
591 if (CAN_EARLY_BRIDGE(peerflags
))
592 ast_rtp_early_bridge(in
, peer
);
594 /* If call has been answered, then the eventual hangup is likely to be normal hangup */
595 in
->hangupcause
= AST_CAUSE_NORMAL_CLEARING
;
596 c
->hangupcause
= AST_CAUSE_NORMAL_CLEARING
;
598 case AST_CONTROL_BUSY
:
599 if (option_verbose
> 2)
600 ast_verbose(VERBOSE_PREFIX_3
"%s is busy\n", c
->name
);
601 in
->hangupcause
= c
->hangupcause
;
604 ast_clear_flag(o
, DIAL_STILLGOING
);
605 HANDLE_CAUSE(AST_CAUSE_BUSY
, in
);
607 case AST_CONTROL_CONGESTION
:
608 if (option_verbose
> 2)
609 ast_verbose(VERBOSE_PREFIX_3
"%s is circuit-busy\n", c
->name
);
610 in
->hangupcause
= c
->hangupcause
;
613 ast_clear_flag(o
, DIAL_STILLGOING
);
614 HANDLE_CAUSE(AST_CAUSE_CONGESTION
, in
);
616 case AST_CONTROL_RINGING
:
617 if (option_verbose
> 2)
618 ast_verbose(VERBOSE_PREFIX_3
"%s is ringing\n", c
->name
);
619 /* Setup early media if appropriate */
620 if (single
&& CAN_EARLY_BRIDGE(peerflags
))
621 ast_rtp_early_bridge(in
, c
);
622 if (!(*sentringing
) && !ast_test_flag(outgoing
, OPT_MUSICBACK
)) {
623 ast_indicate(in
, AST_CONTROL_RINGING
);
627 case AST_CONTROL_PROGRESS
:
628 if (option_verbose
> 2)
629 ast_verbose (VERBOSE_PREFIX_3
"%s is making progress passing it to %s\n", c
->name
, in
->name
);
630 /* Setup early media if appropriate */
631 if (single
&& CAN_EARLY_BRIDGE(peerflags
))
632 ast_rtp_early_bridge(in
, c
);
633 if (!ast_test_flag(outgoing
, OPT_RINGBACK
))
634 ast_indicate(in
, AST_CONTROL_PROGRESS
);
636 case AST_CONTROL_VIDUPDATE
:
637 if (option_verbose
> 2)
638 ast_verbose (VERBOSE_PREFIX_3
"%s requested a video update, passing it to %s\n", c
->name
, in
->name
);
639 ast_indicate(in
, AST_CONTROL_VIDUPDATE
);
641 case AST_CONTROL_PROCEEDING
:
642 if (option_verbose
> 2)
643 ast_verbose (VERBOSE_PREFIX_3
"%s is proceeding passing it to %s\n", c
->name
, in
->name
);
644 if (single
&& CAN_EARLY_BRIDGE(peerflags
))
645 ast_rtp_early_bridge(in
, c
);
646 if (!ast_test_flag(outgoing
, OPT_RINGBACK
))
647 ast_indicate(in
, AST_CONTROL_PROCEEDING
);
649 case AST_CONTROL_HOLD
:
650 if (option_verbose
> 2)
651 ast_verbose(VERBOSE_PREFIX_3
"Call on %s placed on hold\n", c
->name
);
652 ast_indicate(in
, AST_CONTROL_HOLD
);
654 case AST_CONTROL_UNHOLD
:
655 if (option_verbose
> 2)
656 ast_verbose(VERBOSE_PREFIX_3
"Call on %s left from hold\n", c
->name
);
657 ast_indicate(in
, AST_CONTROL_UNHOLD
);
659 case AST_CONTROL_OFFHOOK
:
660 case AST_CONTROL_FLASH
:
661 /* Ignore going off hook and flash */
664 if (!ast_test_flag(outgoing
, OPT_RINGBACK
| OPT_MUSICBACK
)) {
665 if (option_verbose
> 2)
666 ast_verbose(VERBOSE_PREFIX_3
"%s stopped sounds\n", c
->name
);
667 ast_indicate(in
, -1);
673 ast_log(LOG_DEBUG
, "Dunno what to do with control type %d\n", f
->subclass
);
676 /* XXX are we sure the logic is correct ? or we should just switch on f->frametype ? */
677 if (f
->frametype
== AST_FRAME_VOICE
&& !ast_test_flag(outgoing
, OPT_RINGBACK
|OPT_MUSICBACK
)) {
678 if (ast_write(in
, f
))
679 ast_log(LOG_WARNING
, "Unable to forward voice frame\n");
680 } else if (f
->frametype
== AST_FRAME_IMAGE
&& !ast_test_flag(outgoing
, OPT_RINGBACK
|OPT_MUSICBACK
)) {
681 if (ast_write(in
, f
))
682 ast_log(LOG_WARNING
, "Unable to forward image\n");
683 } else if (f
->frametype
== AST_FRAME_TEXT
&& !ast_test_flag(outgoing
, OPT_RINGBACK
|OPT_MUSICBACK
)) {
684 if (ast_write(in
, f
))
685 ast_log(LOG_WARNING
, "Unable to send text\n");
686 } else if (f
->frametype
== AST_FRAME_HTML
&& !ast_test_flag(outgoing
, DIAL_NOFORWARDHTML
)) {
687 if (ast_channel_sendhtml(in
, f
->subclass
, f
->data
, f
->datalen
) == -1)
688 ast_log(LOG_WARNING
, "Unable to send URL\n");
694 struct ast_frame
*f
= ast_read(in
);
696 if (f
&& (f
->frametype
!= AST_FRAME_VOICE
))
697 printf("Frame type: %d, %d\n", f
->frametype
, f
->subclass
);
698 else if (!f
|| (f
->frametype
!= AST_FRAME_VOICE
))
699 printf("Hangup received on %s\n", in
->name
);
701 if (!f
|| ((f
->frametype
== AST_FRAME_CONTROL
) && (f
->subclass
== AST_CONTROL_HANGUP
))) {
704 ast_cdr_noanswer(in
->cdr
);
705 strcpy(status
, "CANCEL");
711 if (f
&& (f
->frametype
== AST_FRAME_DTMF
)) {
712 if (ast_test_flag(peerflags
, OPT_DTMF_EXIT
)) {
713 const char *context
= pbx_builtin_getvar_helper(in
, "EXITCONTEXT");
714 if (onedigit_goto(in
, context
, (char) f
->subclass
, 1)) {
715 if (option_verbose
> 2)
716 ast_verbose(VERBOSE_PREFIX_3
"User hit %c to disconnect call.\n", f
->subclass
);
718 ast_cdr_noanswer(in
->cdr
);
719 *result
= f
->subclass
;
720 strcpy(status
, "CANCEL");
726 if (ast_test_flag(peerflags
, OPT_CALLER_HANGUP
) &&
727 (f
->subclass
== '*')) { /* hmm it it not guaranteed to be '*' anymore. */
728 if (option_verbose
> 2)
729 ast_verbose(VERBOSE_PREFIX_3
"User hit %c to disconnect call.\n", f
->subclass
);
731 ast_cdr_noanswer(in
->cdr
);
732 strcpy(status
, "CANCEL");
738 /* Forward HTML stuff */
739 if (single
&& f
&& (f
->frametype
== AST_FRAME_HTML
) && !ast_test_flag(outgoing
, DIAL_NOFORWARDHTML
))
740 if(ast_channel_sendhtml(outgoing
->chan
, f
->subclass
, f
->data
, f
->datalen
) == -1)
741 ast_log(LOG_WARNING
, "Unable to send URL\n");
744 if (single
&& ((f
->frametype
== AST_FRAME_VOICE
) || (f
->frametype
== AST_FRAME_DTMF_BEGIN
) || (f
->frametype
== AST_FRAME_DTMF_END
))) {
745 if (ast_write(outgoing
->chan
, f
))
746 ast_log(LOG_WARNING
, "Unable to forward voice or dtmf\n");
748 if (single
&& (f
->frametype
== AST_FRAME_CONTROL
) &&
749 ((f
->subclass
== AST_CONTROL_HOLD
) ||
750 (f
->subclass
== AST_CONTROL_UNHOLD
) ||
751 (f
->subclass
== AST_CONTROL_VIDUPDATE
))) {
752 if (option_verbose
> 2)
753 ast_verbose(VERBOSE_PREFIX_3
"%s requested special control %d, passing it to %s\n", in
->name
, f
->subclass
, outgoing
->chan
->name
);
754 ast_indicate_data(outgoing
->chan
, f
->subclass
, f
->data
, f
->datalen
);
758 if (!*to
&& (option_verbose
> 2))
759 ast_verbose(VERBOSE_PREFIX_3
"Nobody picked up in %d ms\n", orig
);
760 if (!*to
|| ast_check_hangup(in
)) {
761 ast_cdr_noanswer(in
->cdr
);
769 static void replace_macro_delimiter(char *s
)
777 /* returns true if there is a valid privacy reply */
778 static int valid_priv_reply(struct ast_flags
*opts
, int res
)
782 if (ast_test_flag(opts
, OPT_PRIVACY
) && res
<= '5')
784 if (ast_test_flag(opts
, OPT_SCREENING
) && res
<= '4')
789 static int dial_exec_full(struct ast_channel
*chan
, void *data
, struct ast_flags
*peerflags
, int *continue_exec
)
792 struct ast_module_user
*u
;
794 struct dial_localuser
*outgoing
= NULL
;
795 struct ast_channel
*peer
;
798 int numcongestion
= 0;
802 char cidname
[AST_MAX_EXTENSION
] = "";
804 unsigned int calldurationlimit
= 0;
806 long play_warning
= 0;
807 long warning_freq
= 0;
808 const char *warning_sound
= NULL
;
809 const char *end_sound
= NULL
;
810 const char *start_sound
= NULL
;
811 char *dtmfcalled
= NULL
, *dtmfcalling
= NULL
;
812 char status
[256] = "INVALIDARGS";
813 int play_to_caller
= 0, play_to_callee
= 0;
814 int sentringing
= 0, moh
= 0;
815 const char *outbound_group
= NULL
;
818 char privintro
[1024];
822 AST_DECLARE_APP_ARGS(args
,
824 AST_APP_ARG(timeout
);
825 AST_APP_ARG(options
);
828 struct ast_flags opts
= { 0, };
829 char *opt_args
[OPT_ARG_ARRAY_SIZE
];
831 if (ast_strlen_zero(data
)) {
832 ast_log(LOG_WARNING
, "Dial requires an argument (technology/number)\n");
833 pbx_builtin_setvar_helper(chan
, "DIALSTATUS", status
);
837 u
= ast_module_user_add(chan
);
839 parse
= ast_strdupa(data
);
841 AST_STANDARD_APP_ARGS(args
, parse
);
843 if (!ast_strlen_zero(args
.options
) &&
844 ast_app_parse_options(dial_exec_options
, &opts
, opt_args
, args
.options
)) {
845 pbx_builtin_setvar_helper(chan
, "DIALSTATUS", status
);
849 if (ast_strlen_zero(args
.peers
)) {
850 ast_log(LOG_WARNING
, "Dial requires an argument (technology/number)\n");
851 pbx_builtin_setvar_helper(chan
, "DIALSTATUS", status
);
855 if (ast_test_flag(&opts
, OPT_OPERMODE
)) {
856 if (ast_strlen_zero(opt_args
[OPT_ARG_OPERMODE
]))
858 else opermode
= atoi(opt_args
[OPT_ARG_OPERMODE
]);
859 if (option_verbose
> 2)
860 ast_verbose(VERBOSE_PREFIX_3
"Setting operator services mode to %d.\n", opermode
);
863 if (ast_test_flag(&opts
, OPT_DURATION_STOP
) && !ast_strlen_zero(opt_args
[OPT_ARG_DURATION_STOP
])) {
864 calldurationlimit
= atoi(opt_args
[OPT_ARG_DURATION_STOP
]);
865 if (!calldurationlimit
) {
866 ast_log(LOG_WARNING
, "Dial does not accept S(%s), hanging up.\n", opt_args
[OPT_ARG_DURATION_STOP
]);
867 pbx_builtin_setvar_helper(chan
, "DIALSTATUS", status
);
870 if (option_verbose
> 2)
871 ast_verbose(VERBOSE_PREFIX_3
"Setting call duration limit to %d seconds.\n", calldurationlimit
);
874 if (ast_test_flag(&opts
, OPT_SENDDTMF
) && !ast_strlen_zero(opt_args
[OPT_ARG_SENDDTMF
])) {
875 dtmfcalling
= opt_args
[OPT_ARG_SENDDTMF
];
876 dtmfcalled
= strsep(&dtmfcalling
, ":");
879 if (ast_test_flag(&opts
, OPT_DURATION_LIMIT
) && !ast_strlen_zero(opt_args
[OPT_ARG_DURATION_LIMIT
])) {
880 char *limit_str
, *warning_str
, *warnfreq_str
;
883 warnfreq_str
= opt_args
[OPT_ARG_DURATION_LIMIT
];
884 limit_str
= strsep(&warnfreq_str
, ":");
885 warning_str
= strsep(&warnfreq_str
, ":");
887 timelimit
= atol(limit_str
);
889 play_warning
= atol(warning_str
);
891 warning_freq
= atol(warnfreq_str
);
894 ast_log(LOG_WARNING
, "Dial does not accept L(%s), hanging up.\n", limit_str
);
896 } else if (play_warning
> timelimit
) {
897 /* If the first warning is requested _after_ the entire call would end,
898 and no warning frequency is requested, then turn off the warning. If
899 a warning frequency is requested, reduce the 'first warning' time by
900 that frequency until it falls within the call's total time limit.
907 while (play_warning
> timelimit
)
908 play_warning
-= warning_freq
;
909 if (play_warning
< 1)
910 play_warning
= warning_freq
= 0;
914 var
= pbx_builtin_getvar_helper(chan
,"LIMIT_PLAYAUDIO_CALLER");
915 play_to_caller
= var
? ast_true(var
) : 1;
917 var
= pbx_builtin_getvar_helper(chan
,"LIMIT_PLAYAUDIO_CALLEE");
918 play_to_callee
= var
? ast_true(var
) : 0;
920 if (!play_to_caller
&& !play_to_callee
)
923 var
= pbx_builtin_getvar_helper(chan
,"LIMIT_WARNING_FILE");
924 warning_sound
= S_OR(var
, "timeleft");
926 var
= pbx_builtin_getvar_helper(chan
,"LIMIT_TIMEOUT_FILE");
927 end_sound
= S_OR(var
, NULL
); /* XXX not much of a point in doing this! */
929 var
= pbx_builtin_getvar_helper(chan
,"LIMIT_CONNECT_FILE");
930 start_sound
= S_OR(var
, NULL
); /* XXX not much of a point in doing this! */
932 /* undo effect of S(x) in case they are both used */
933 calldurationlimit
= 0;
934 /* more efficient to do it like S(x) does since no advanced opts */
935 if (!play_warning
&& !start_sound
&& !end_sound
&& timelimit
) {
936 calldurationlimit
= timelimit
/ 1000;
937 if (option_verbose
> 2)
938 ast_verbose(VERBOSE_PREFIX_3
"Setting call duration limit to %d seconds.\n", calldurationlimit
);
939 timelimit
= play_to_caller
= play_to_callee
= play_warning
= warning_freq
= 0;
940 } else if (option_verbose
> 2) {
941 ast_verbose(VERBOSE_PREFIX_3
"Limit Data for this call:\n");
942 ast_verbose(VERBOSE_PREFIX_4
"timelimit = %ld\n", timelimit
);
943 ast_verbose(VERBOSE_PREFIX_4
"play_warning = %ld\n", play_warning
);
944 ast_verbose(VERBOSE_PREFIX_4
"play_to_caller = %s\n", play_to_caller
? "yes" : "no");
945 ast_verbose(VERBOSE_PREFIX_4
"play_to_callee = %s\n", play_to_callee
? "yes" : "no");
946 ast_verbose(VERBOSE_PREFIX_4
"warning_freq = %ld\n", warning_freq
);
947 ast_verbose(VERBOSE_PREFIX_4
"start_sound = %s\n", start_sound
);
948 ast_verbose(VERBOSE_PREFIX_4
"warning_sound = %s\n", warning_sound
);
949 ast_verbose(VERBOSE_PREFIX_4
"end_sound = %s\n", end_sound
);
953 if (ast_test_flag(&opts
, OPT_RESETCDR
) && chan
->cdr
)
954 ast_cdr_reset(chan
->cdr
, NULL
);
955 if (ast_test_flag(&opts
, OPT_PRIVACY
) && ast_strlen_zero(opt_args
[OPT_ARG_PRIVACY
]))
956 opt_args
[OPT_ARG_PRIVACY
] = ast_strdupa(chan
->exten
);
957 if (ast_test_flag(&opts
, OPT_PRIVACY
) || ast_test_flag(&opts
, OPT_SCREENING
)) {
959 char *l
= chan
->cid
.cid_num
; /* XXX watch out, we are overwriting it */
960 if (!ast_strlen_zero(l
)) {
961 ast_shrink_phone_number(l
);
962 if( ast_test_flag(&opts
, OPT_PRIVACY
) ) {
963 if (option_verbose
> 2)
964 ast_verbose(VERBOSE_PREFIX_3
"Privacy DB is '%s', clid is '%s'\n",
965 opt_args
[OPT_ARG_PRIVACY
], l
);
966 privdb_val
= ast_privacy_check(opt_args
[OPT_ARG_PRIVACY
], l
);
969 if (option_verbose
> 2)
970 ast_verbose(VERBOSE_PREFIX_3
"Privacy Screening, clid is '%s'\n", l
);
971 privdb_val
= AST_PRIVACY_UNKNOWN
;
976 tnam
= ast_strdupa(chan
->name
);
977 /* clean the channel name so slashes don't try to end up in disk file name */
978 for(tn2
= tnam
; *tn2
; tn2
++) {
980 *tn2
= '='; /* any other chars to be afraid of? */
982 if (option_verbose
> 2)
983 ast_verbose(VERBOSE_PREFIX_3
"Privacy-- callerid is empty\n");
985 snprintf(callerid
, sizeof(callerid
), "NOCALLERID_%s%s", chan
->exten
, tnam
);
987 privdb_val
= AST_PRIVACY_UNKNOWN
;
990 ast_copy_string(privcid
,l
,sizeof(privcid
));
992 if( strncmp(privcid
,"NOCALLERID",10) != 0 && ast_test_flag(&opts
, OPT_SCREEN_NOCLID
) ) { /* if callerid is set, and ast_test_flag(&opts, OPT_SCREEN_NOCLID) is set also */
993 if (option_verbose
> 2)
994 ast_verbose( VERBOSE_PREFIX_3
"CallerID set (%s); N option set; Screening should be off\n", privcid
);
995 privdb_val
= AST_PRIVACY_ALLOW
;
997 else if(ast_test_flag(&opts
, OPT_SCREEN_NOCLID
) && strncmp(privcid
,"NOCALLERID",10) == 0 ) {
998 if (option_verbose
> 2)
999 ast_verbose( VERBOSE_PREFIX_3
"CallerID blank; N option set; Screening should happen; dbval is %d\n", privdb_val
);
1002 if(privdb_val
== AST_PRIVACY_DENY
) {
1003 ast_copy_string(status
, "NOANSWER", sizeof(status
));
1004 if (option_verbose
> 2)
1005 ast_verbose( VERBOSE_PREFIX_3
"Privacy DB reports PRIVACY_DENY for this callerid. Dial reports unavailable\n");
1009 else if(privdb_val
== AST_PRIVACY_KILL
) {
1010 ast_copy_string(status
, "DONTCALL", sizeof(status
));
1011 if (ast_opt_priority_jumping
|| ast_test_flag(&opts
, OPT_PRIORITY_JUMP
)) {
1012 ast_goto_if_exists(chan
, chan
->context
, chan
->exten
, chan
->priority
+ 201);
1015 goto out
; /* Is this right? */
1017 else if(privdb_val
== AST_PRIVACY_TORTURE
) {
1018 ast_copy_string(status
, "TORTURE", sizeof(status
));
1019 if (ast_opt_priority_jumping
|| ast_test_flag(&opts
, OPT_PRIORITY_JUMP
)) {
1020 ast_goto_if_exists(chan
, chan
->context
, chan
->exten
, chan
->priority
+ 301);
1023 goto out
; /* is this right??? */
1025 else if(privdb_val
== AST_PRIVACY_UNKNOWN
) {
1026 /* Get the user's intro, store it in priv-callerintros/$CID,
1027 unless it is already there-- this should be done before the
1028 call is actually dialed */
1030 /* make sure the priv-callerintros dir actually exists */
1031 snprintf(privintro
, sizeof(privintro
), "%s/sounds/priv-callerintros", ast_config_AST_DATA_DIR
);
1032 if (mkdir(privintro
, 0755) && errno
!= EEXIST
) {
1033 ast_log(LOG_WARNING
, "privacy: can't create directory priv-callerintros: %s\n", strerror(errno
));
1038 snprintf(privintro
,sizeof(privintro
), "priv-callerintros/%s", privcid
);
1039 if( ast_fileexists(privintro
,NULL
,NULL
) > 0 && strncmp(privcid
,"NOCALLERID",10) != 0) {
1040 /* the DELUX version of this code would allow this caller the
1041 option to hear and retape their previously recorded intro.
1045 int duration
; /* for feedback from play_and_wait */
1046 /* the file doesn't exist yet. Let the caller submit his
1047 vocal intro for posterity */
1048 /* priv-recordintro script:
1050 "At the tone, please say your name:"
1054 res
= ast_play_and_record(chan
, "priv-recordintro", privintro
, 4, "gsm", &duration
, 128, 2000, 0); /* NOTE: I've reduced the total time to 4 sec */
1055 /* don't think we'll need a lock removed, we took care of
1056 conflicts by naming the privintro file */
1058 /* Delete the file regardless since they hung up during recording */
1059 ast_filedelete(privintro
, NULL
);
1060 if( ast_fileexists(privintro
,NULL
,NULL
) > 0 )
1061 ast_log(LOG_NOTICE
,"privacy: ast_filedelete didn't do its job on %s\n", privintro
);
1062 else if (option_verbose
> 2)
1063 ast_verbose( VERBOSE_PREFIX_3
"Successfully deleted %s intro file\n", privintro
);
1066 if( !ast_streamfile(chan
, "vm-dialout", chan
->language
) )
1067 ast_waitstream(chan
, "");
1075 /* If a channel group has been specified, get it for use when we create peer channels */
1076 if ((outbound_group
= pbx_builtin_getvar_helper(chan
, "OUTBOUND_GROUP_ONCE"))) {
1077 outbound_group
= ast_strdupa(outbound_group
);
1078 pbx_builtin_setvar_helper(chan
, "OUTBOUND_GROUP_ONCE", NULL
);
1080 outbound_group
= pbx_builtin_getvar_helper(chan
, "OUTBOUND_GROUP");
1083 ast_copy_flags(peerflags
, &opts
, OPT_DTMF_EXIT
| OPT_GO_ON
| OPT_ORIGINAL_CLID
| OPT_CALLER_HANGUP
| OPT_IGNORE_FORWARDING
);
1084 /* loop through the list of dial destinations */
1086 while ((cur
= strsep(&rest
, "&")) ) {
1087 struct dial_localuser
*tmp
;
1088 /* Get a technology/[device:]number pair */
1090 char *tech
= strsep(&number
, "/");
1092 ast_log(LOG_WARNING
, "Dial argument takes format (technology/[device:]number1)\n");
1095 if (!(tmp
= ast_calloc(1, sizeof(*tmp
))))
1098 ast_copy_flags(tmp
, &opts
,
1099 OPT_CALLEE_TRANSFER
| OPT_CALLER_TRANSFER
|
1100 OPT_CALLEE_HANGUP
| OPT_CALLER_HANGUP
|
1101 OPT_CALLEE_MONITOR
| OPT_CALLER_MONITOR
|
1102 OPT_CALLEE_PARK
| OPT_CALLER_PARK
|
1103 OPT_RINGBACK
| OPT_MUSICBACK
| OPT_FORCECLID
);
1104 ast_set2_flag(tmp
, args
.url
, DIAL_NOFORWARDHTML
);
1106 ast_copy_string(numsubst
, number
, sizeof(numsubst
));
1107 /* Request the peer */
1108 tmp
->chan
= ast_request(tech
, chan
->nativeformats
, numsubst
, &cause
);
1110 /* If we can't, just go on to the next call */
1111 ast_log(LOG_WARNING
, "Unable to create channel of type '%s' (cause %d - %s)\n", tech
, cause
, ast_cause2str(cause
));
1112 HANDLE_CAUSE(cause
, chan
);
1113 if (!rest
) /* we are on the last destination */
1114 chan
->hangupcause
= cause
;
1118 pbx_builtin_setvar_helper(tmp
->chan
, "DIALEDPEERNUMBER", numsubst
);
1119 if (!ast_strlen_zero(tmp
->chan
->call_forward
)) {
1123 ast_copy_string(tmpchan
, tmp
->chan
->call_forward
, sizeof(tmpchan
));
1124 if ((stuff
= strchr(tmpchan
, '/'))) {
1128 snprintf(tmpchan
, sizeof(tmpchan
), "%s@%s", tmp
->chan
->call_forward
, tmp
->chan
->context
);
1133 if (tmp
->forwards
< AST_MAX_FORWARDS
) {
1134 if (option_verbose
> 2)
1135 ast_verbose(VERBOSE_PREFIX_3
"Now forwarding %s to '%s/%s' (thanks to %s)\n", chan
->name
, tech
, stuff
, tmp
->chan
->name
);
1136 ast_hangup(tmp
->chan
);
1137 /* If we have been told to ignore forwards, just set this channel to null and continue processing extensions normally */
1138 if (ast_test_flag(&opts
, OPT_IGNORE_FORWARDING
)) {
1140 cause
= AST_CAUSE_BUSY
;
1141 if (option_verbose
> 2)
1142 ast_verbose(VERBOSE_PREFIX_3
"Forwarding %s to '%s/%s' prevented.\n", chan
->name
, tech
, stuff
);
1144 tmp
->chan
= ast_request(tech
, chan
->nativeformats
, stuff
, &cause
);
1147 ast_log(LOG_NOTICE
, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech
, stuff
, cause
);
1149 ast_channel_inherit_variables(chan
, tmp
->chan
);
1151 if (option_verbose
> 2)
1152 ast_verbose(VERBOSE_PREFIX_3
"Too many forwards from %s\n", tmp
->chan
->name
);
1153 ast_hangup(tmp
->chan
);
1155 cause
= AST_CAUSE_CONGESTION
;
1158 HANDLE_CAUSE(cause
, chan
);
1164 /* Setup outgoing SDP to match incoming one */
1165 ast_rtp_make_compatible(tmp
->chan
, chan
, !outgoing
&& !rest
);
1167 /* Inherit specially named variables from parent channel */
1168 ast_channel_inherit_variables(chan
, tmp
->chan
);
1170 tmp
->chan
->appl
= "AppDial";
1171 tmp
->chan
->data
= "(Outgoing Line)";
1172 tmp
->chan
->whentohangup
= 0;
1174 if (tmp
->chan
->cid
.cid_num
)
1175 free(tmp
->chan
->cid
.cid_num
);
1176 tmp
->chan
->cid
.cid_num
= ast_strdup(chan
->cid
.cid_num
);
1178 if (tmp
->chan
->cid
.cid_name
)
1179 free(tmp
->chan
->cid
.cid_name
);
1180 tmp
->chan
->cid
.cid_name
= ast_strdup(chan
->cid
.cid_name
);
1182 if (tmp
->chan
->cid
.cid_ani
)
1183 free(tmp
->chan
->cid
.cid_ani
);
1184 tmp
->chan
->cid
.cid_ani
= ast_strdup(chan
->cid
.cid_ani
);
1186 /* Copy language from incoming to outgoing */
1187 ast_string_field_set(tmp
->chan
, language
, chan
->language
);
1188 ast_string_field_set(tmp
->chan
, accountcode
, chan
->accountcode
);
1189 tmp
->chan
->cdrflags
= chan
->cdrflags
;
1190 if (ast_strlen_zero(tmp
->chan
->musicclass
))
1191 ast_string_field_set(tmp
->chan
, musicclass
, chan
->musicclass
);
1192 /* XXX don't we free previous values ? */
1193 tmp
->chan
->cid
.cid_rdnis
= ast_strdup(chan
->cid
.cid_rdnis
);
1194 /* Pass callingpres setting */
1195 tmp
->chan
->cid
.cid_pres
= chan
->cid
.cid_pres
;
1196 /* Pass type of number */
1197 tmp
->chan
->cid
.cid_ton
= chan
->cid
.cid_ton
;
1198 /* Pass type of tns */
1199 tmp
->chan
->cid
.cid_tns
= chan
->cid
.cid_tns
;
1200 /* Presense of ADSI CPE on outgoing channel follows ours */
1201 tmp
->chan
->adsicpe
= chan
->adsicpe
;
1202 /* Pass the transfer capability */
1203 tmp
->chan
->transfercapability
= chan
->transfercapability
;
1205 /* If we have an outbound group, set this peer channel to it */
1207 ast_app_group_set_channel(tmp
->chan
, outbound_group
);
1209 /* Inherit context and extension */
1210 if (!ast_strlen_zero(chan
->macrocontext
))
1211 ast_copy_string(tmp
->chan
->dialcontext
, chan
->macrocontext
, sizeof(tmp
->chan
->dialcontext
));
1213 ast_copy_string(tmp
->chan
->dialcontext
, chan
->context
, sizeof(tmp
->chan
->dialcontext
));
1214 if (!ast_strlen_zero(chan
->macroexten
))
1215 ast_copy_string(tmp
->chan
->exten
, chan
->macroexten
, sizeof(tmp
->chan
->exten
));
1217 ast_copy_string(tmp
->chan
->exten
, chan
->exten
, sizeof(tmp
->chan
->exten
));
1219 /* Place the call, but don't wait on the answer */
1220 res
= ast_call(tmp
->chan
, numsubst
, 0);
1222 /* Save the info in cdr's that we called them */
1224 ast_cdr_setdestchan(chan
->cdr
, tmp
->chan
->name
);
1226 /* check the results of ast_call */
1228 /* Again, keep going even if there's an error */
1230 ast_log(LOG_DEBUG
, "ast call on peer returned %d\n", res
);
1231 if (option_verbose
> 2)
1232 ast_verbose(VERBOSE_PREFIX_3
"Couldn't call %s\n", numsubst
);
1233 ast_hangup(tmp
->chan
);
1238 senddialevent(chan
, tmp
->chan
);
1239 if (option_verbose
> 2)
1240 ast_verbose(VERBOSE_PREFIX_3
"Called %s\n", numsubst
);
1241 if (!ast_test_flag(peerflags
, OPT_ORIGINAL_CLID
))
1242 ast_set_callerid(tmp
->chan
, S_OR(chan
->macroexten
, chan
->exten
), get_cid_name(cidname
, sizeof(cidname
), chan
), NULL
);
1244 /* Put them in the list of outgoing thingies... We're ready now.
1245 XXX If we're forcibly removed, these outgoing calls won't get
1247 ast_set_flag(tmp
, DIAL_STILLGOING
);
1248 tmp
->next
= outgoing
;
1250 /* If this line is up, don't try anybody else */
1251 if (outgoing
->chan
->_state
== AST_STATE_UP
)
1255 if (ast_strlen_zero(args
.timeout
)) {
1258 to
= atoi(args
.timeout
);
1262 ast_log(LOG_WARNING
, "Invalid timeout specified: '%s'\n", args
.timeout
);
1266 strcpy(status
, "CHANUNAVAIL");
1268 /* Our status will at least be NOANSWER */
1269 strcpy(status
, "NOANSWER");
1270 if (ast_test_flag(outgoing
, OPT_MUSICBACK
)) {
1272 if (!ast_strlen_zero(opt_args
[OPT_ARG_MUSICBACK
])) {
1273 char *original_moh
= ast_strdupa(chan
->musicclass
);
1274 ast_string_field_set(chan
, musicclass
, opt_args
[OPT_ARG_MUSICBACK
]);
1275 ast_moh_start(chan
, opt_args
[OPT_ARG_MUSICBACK
], NULL
);
1276 ast_string_field_set(chan
, musicclass
, original_moh
);
1278 ast_moh_start(chan
, NULL
, NULL
);
1280 ast_indicate(chan
, AST_CONTROL_PROGRESS
);
1281 } else if (ast_test_flag(outgoing
, OPT_RINGBACK
)) {
1282 ast_indicate(chan
, AST_CONTROL_RINGING
);
1288 peer
= wait_for_answer(chan
, outgoing
, &to
, peerflags
, &sentringing
, status
, sizeof(status
), numbusy
, numnochan
, numcongestion
, ast_test_flag(&opts
, OPT_PRIORITY_JUMP
), &result
);
1293 } else if (to
) { /* Musta gotten hung up */
1295 } else { /* Nobody answered, next please? */
1298 /* almost done, although the 'else' block is 400 lines */
1301 time_t end_time
, answer_time
= time(NULL
);
1303 strcpy(status
, "ANSWER");
1304 /* Ah ha! Someone answered within the desired timeframe. Of course after this
1305 we will always return with -1 so that it is hung up properly after the
1307 hanguptree(outgoing
, peer
);
1309 /* If appropriate, log that we have a destination channel */
1311 ast_cdr_setdestchan(chan
->cdr
, peer
->name
);
1313 pbx_builtin_setvar_helper(chan
, "DIALEDPEERNAME", peer
->name
);
1315 number
= pbx_builtin_getvar_helper(peer
, "DIALEDPEERNUMBER");
1318 pbx_builtin_setvar_helper(chan
, "DIALEDPEERNUMBER", number
);
1319 if (!ast_strlen_zero(args
.url
) && ast_channel_supports_html(peer
) ) {
1321 ast_log(LOG_DEBUG
, "app_dial: sendurl=%s.\n", args
.url
);
1322 ast_channel_sendurl( peer
, args
.url
);
1324 if ( (ast_test_flag(&opts
, OPT_PRIVACY
) || ast_test_flag(&opts
, OPT_SCREENING
)) && privdb_val
== AST_PRIVACY_UNKNOWN
) {
1328 /* Get the user's intro, store it in priv-callerintros/$CID,
1329 unless it is already there-- this should be done before the
1330 call is actually dialed */
1332 /* all ring indications and moh for the caller has been halted as soon as the
1333 target extension was picked up. We are going to have to kill some
1334 time and make the caller believe the peer hasn't picked up yet */
1336 if (ast_test_flag(&opts
, OPT_MUSICBACK
) && !ast_strlen_zero(opt_args
[OPT_ARG_MUSICBACK
])) {
1337 char *original_moh
= ast_strdupa(chan
->musicclass
);
1338 ast_indicate(chan
, -1);
1339 ast_string_field_set(chan
, musicclass
, opt_args
[OPT_ARG_MUSICBACK
]);
1340 ast_moh_start(chan
, opt_args
[OPT_ARG_MUSICBACK
], NULL
);
1341 ast_string_field_set(chan
, musicclass
, original_moh
);
1342 } else if (ast_test_flag(&opts
, OPT_RINGBACK
)) {
1343 ast_indicate(chan
, AST_CONTROL_RINGING
);
1347 /* Start autoservice on the other chan ?? */
1348 res2
= ast_autoservice_start(chan
);
1349 /* Now Stream the File */
1350 for (loopcount
= 0; loopcount
< 3; loopcount
++) {
1351 if (res2
&& loopcount
== 0) /* error in ast_autoservice_start() */
1353 if (!res2
) /* on timeout, play the message again */
1354 res2
= ast_play_and_wait(peer
,"priv-callpending");
1355 if (!valid_priv_reply(&opts
, res2
))
1357 /* priv-callpending script:
1358 "I have a caller waiting, who introduces themselves as:"
1361 res2
= ast_play_and_wait(peer
,privintro
);
1362 if (!valid_priv_reply(&opts
, res2
))
1364 /* now get input from the called party, as to their choice */
1366 /* XXX can we have both, or they are mutually exclusive ? */
1367 if( ast_test_flag(&opts
, OPT_PRIVACY
) )
1368 res2
= ast_play_and_wait(peer
,"priv-callee-options");
1369 if( ast_test_flag(&opts
, OPT_SCREENING
) )
1370 res2
= ast_play_and_wait(peer
,"screen-callee-options");
1372 /*! \page DialPrivacy Dial Privacy scripts
1373 \par priv-callee-options script:
1374 "Dial 1 if you wish this caller to reach you directly in the future,
1375 and immediately connect to their incoming call
1376 Dial 2 if you wish to send this caller to voicemail now and
1378 Dial 3 to send this caller to the torture menus, now and forevermore.
1379 Dial 4 to send this caller to a simple "go away" menu, now and forevermore.
1380 Dial 5 to allow this caller to come straight thru to you in the future,
1381 but right now, just this once, send them to voicemail."
1382 \par screen-callee-options script:
1383 "Dial 1 if you wish to immediately connect to the incoming call
1384 Dial 2 if you wish to send this caller to voicemail.
1385 Dial 3 to send this caller to the torture menus.
1386 Dial 4 to send this caller to a simple "go away" menu.
1388 if (valid_priv_reply(&opts
, res2
))
1390 /* invalid option */
1391 res2
= ast_play_and_wait(peer
, "vm-sorry");
1394 if (ast_test_flag(&opts
, OPT_MUSICBACK
)) {
1396 } else if (ast_test_flag(&opts
, OPT_RINGBACK
)) {
1397 ast_indicate(chan
, -1);
1400 ast_autoservice_stop(chan
);
1404 if( ast_test_flag(&opts
, OPT_PRIVACY
) ) {
1405 if (option_verbose
> 2)
1406 ast_verbose(VERBOSE_PREFIX_3
"--Set privacy database entry %s/%s to ALLOW\n",
1407 opt_args
[OPT_ARG_PRIVACY
], privcid
);
1408 ast_privacy_set(opt_args
[OPT_ARG_PRIVACY
], privcid
, AST_PRIVACY_ALLOW
);
1412 if( ast_test_flag(&opts
, OPT_PRIVACY
) ) {
1413 if (option_verbose
> 2)
1414 ast_verbose(VERBOSE_PREFIX_3
"--Set privacy database entry %s/%s to DENY\n",
1415 opt_args
[OPT_ARG_PRIVACY
], privcid
);
1416 ast_privacy_set(opt_args
[OPT_ARG_PRIVACY
], privcid
, AST_PRIVACY_DENY
);
1418 ast_copy_string(status
, "NOANSWER", sizeof(status
));
1419 ast_hangup(peer
); /* hang up on the callee -- he didn't want to talk anyway! */
1423 if( ast_test_flag(&opts
, OPT_PRIVACY
) ) {
1424 if (option_verbose
> 2)
1425 ast_verbose(VERBOSE_PREFIX_3
"--Set privacy database entry %s/%s to TORTURE\n",
1426 opt_args
[OPT_ARG_PRIVACY
], privcid
);
1427 ast_privacy_set(opt_args
[OPT_ARG_PRIVACY
], privcid
, AST_PRIVACY_TORTURE
);
1429 ast_copy_string(status
, "TORTURE", sizeof(status
));
1432 ast_hangup(peer
); /* hang up on the caller -- he didn't want to talk anyway! */
1433 goto out
; /* Is this right? */
1435 if( ast_test_flag(&opts
, OPT_PRIVACY
) ) {
1436 if (option_verbose
> 2)
1437 ast_verbose(VERBOSE_PREFIX_3
"--Set privacy database entry %s/%s to KILL\n",
1438 opt_args
[OPT_ARG_PRIVACY
], privcid
);
1439 ast_privacy_set(opt_args
[OPT_ARG_PRIVACY
], privcid
, AST_PRIVACY_KILL
);
1442 ast_copy_string(status
, "DONTCALL", sizeof(status
));
1444 ast_hangup(peer
); /* hang up on the caller -- he didn't want to talk anyway! */
1445 goto out
; /* Is this right? */
1447 if( ast_test_flag(&opts
, OPT_PRIVACY
) ) {
1448 if (option_verbose
> 2)
1449 ast_verbose(VERBOSE_PREFIX_3
"--Set privacy database entry %s/%s to ALLOW\n",
1450 opt_args
[OPT_ARG_PRIVACY
], privcid
);
1451 ast_privacy_set(opt_args
[OPT_ARG_PRIVACY
], privcid
, AST_PRIVACY_ALLOW
);
1452 ast_hangup(peer
); /* hang up on the caller -- he didn't want to talk anyway! */
1455 } /* if not privacy, then 5 is the same as "default" case */
1456 default: /* bad input or -1 if failure to start autoservice */
1457 /* well, if the user messes up, ... he had his chance... What Is The Best Thing To Do? */
1458 /* well, there seems basically two choices. Just patch the caller thru immediately,
1459 or,... put 'em thru to voicemail. */
1460 /* since the callee may have hung up, let's do the voicemail thing, no database decision */
1461 ast_log(LOG_NOTICE
, "privacy: no valid response from the callee. Sending the caller to voicemail, the callee isn't responding\n");
1462 ast_hangup(peer
); /* hang up on the callee -- he didn't want to talk anyway! */
1467 /* XXX once again, this path is only taken in the case '1', so it could be
1468 * moved there, although i am not really sure that this is correct - maybe
1469 * the check applies to other cases as well.
1471 /* if the intro is NOCALLERID, then there's no reason to leave it on disk, it'll
1472 just clog things up, and it's not useful information, not being tied to a CID */
1473 if( strncmp(privcid
,"NOCALLERID",10) == 0 || ast_test_flag(&opts
, OPT_SCREEN_NOINTRO
) ) {
1474 ast_filedelete(privintro
, NULL
);
1475 if( ast_fileexists(privintro
, NULL
, NULL
) > 0 )
1476 ast_log(LOG_NOTICE
, "privacy: ast_filedelete didn't do its job on %s\n", privintro
);
1477 else if (option_verbose
> 2)
1478 ast_verbose(VERBOSE_PREFIX_3
"Successfully deleted %s intro file\n", privintro
);
1481 if (!ast_test_flag(&opts
, OPT_ANNOUNCE
) || ast_strlen_zero(opt_args
[OPT_ARG_ANNOUNCE
])) {
1485 /* Start autoservice on the other chan */
1486 res
= ast_autoservice_start(chan
);
1487 /* Now Stream the File */
1489 res
= ast_streamfile(peer
, opt_args
[OPT_ARG_ANNOUNCE
], peer
->language
);
1491 digit
= ast_waitstream(peer
, AST_DIGIT_ANY
);
1493 /* Ok, done. stop autoservice */
1494 res
= ast_autoservice_stop(chan
);
1495 if (digit
> 0 && !res
)
1496 res
= ast_senddigit(chan
, digit
);
1502 if (chan
&& peer
&& ast_test_flag(&opts
, OPT_GOTO
) && !ast_strlen_zero(opt_args
[OPT_ARG_GOTO
])) {
1503 replace_macro_delimiter(opt_args
[OPT_ARG_GOTO
]);
1504 ast_parseable_goto(chan
, opt_args
[OPT_ARG_GOTO
]);
1505 ast_parseable_goto(peer
, opt_args
[OPT_ARG_GOTO
]);
1507 ast_pbx_start(peer
);
1508 hanguptree(outgoing
, NULL
);
1515 if (ast_test_flag(&opts
, OPT_CALLEE_MACRO
) && !ast_strlen_zero(opt_args
[OPT_ARG_CALLEE_MACRO
])) {
1516 struct ast_app
*theapp
;
1517 const char *macro_result
;
1519 res
= ast_autoservice_start(chan
);
1521 ast_log(LOG_ERROR
, "Unable to start autoservice on calling channel\n");
1525 theapp
= pbx_findapp("Macro");
1527 if (theapp
&& !res
) { /* XXX why check res here ? */
1528 replace_macro_delimiter(opt_args
[OPT_ARG_CALLEE_MACRO
]);
1529 res
= pbx_exec(peer
, theapp
, opt_args
[OPT_ARG_CALLEE_MACRO
]);
1530 ast_log(LOG_DEBUG
, "Macro exited with status %d\n", res
);
1533 ast_log(LOG_ERROR
, "Could not find application Macro\n");
1537 if (ast_autoservice_stop(chan
) < 0) {
1538 ast_log(LOG_ERROR
, "Could not stop autoservice on calling channel\n");
1542 if (!res
&& (macro_result
= pbx_builtin_getvar_helper(peer
, "MACRO_RESULT"))) {
1543 char *macro_transfer_dest
;
1545 if (!strcasecmp(macro_result
, "BUSY")) {
1546 ast_copy_string(status
, macro_result
, sizeof(status
));
1547 if (ast_opt_priority_jumping
|| ast_test_flag(&opts
, OPT_PRIORITY_JUMP
)) {
1548 if (!ast_goto_if_exists(chan
, NULL
, NULL
, chan
->priority
+ 101)) {
1549 ast_set_flag(peerflags
, OPT_GO_ON
);
1552 ast_set_flag(peerflags
, OPT_GO_ON
);
1554 } else if (!strcasecmp(macro_result
, "CONGESTION") || !strcasecmp(macro_result
, "CHANUNAVAIL")) {
1555 ast_copy_string(status
, macro_result
, sizeof(status
));
1556 ast_set_flag(peerflags
, OPT_GO_ON
);
1558 } else if (!strcasecmp(macro_result
, "CONTINUE")) {
1559 /* hangup peer and keep chan alive assuming the macro has changed
1560 the context / exten / priority or perhaps
1561 the next priority in the current exten is desired.
1563 ast_set_flag(peerflags
, OPT_GO_ON
);
1565 } else if (!strcasecmp(macro_result
, "ABORT")) {
1566 /* Hangup both ends unless the caller has the g flag */
1568 } else if (!strncasecmp(macro_result
, "GOTO:", 5) && (macro_transfer_dest
= ast_strdupa(macro_result
+ 5))) {
1570 /* perform a transfer to a new extension */
1571 if (strchr(macro_transfer_dest
, '^')) { /* context^exten^priority*/
1572 replace_macro_delimiter(macro_transfer_dest
);
1573 if (!ast_parseable_goto(chan
, macro_transfer_dest
))
1574 ast_set_flag(peerflags
, OPT_GO_ON
);
1582 if (calldurationlimit
> 0) {
1583 peer
->whentohangup
= time(NULL
) + calldurationlimit
;
1585 if (!ast_strlen_zero(dtmfcalled
)) {
1586 if (option_verbose
> 2)
1587 ast_verbose(VERBOSE_PREFIX_3
"Sending DTMF '%s' to the called party.\n", dtmfcalled
);
1588 res
= ast_dtmf_stream(peer
,chan
,dtmfcalled
,250);
1590 if (!ast_strlen_zero(dtmfcalling
)) {
1591 if (option_verbose
> 2)
1592 ast_verbose(VERBOSE_PREFIX_3
"Sending DTMF '%s' to the calling party.\n", dtmfcalling
);
1593 res
= ast_dtmf_stream(chan
,peer
,dtmfcalling
,250);
1598 struct ast_bridge_config config
;
1600 memset(&config
,0,sizeof(struct ast_bridge_config
));
1602 ast_set_flag(&(config
.features_caller
), AST_FEATURE_PLAY_WARNING
);
1604 ast_set_flag(&(config
.features_callee
), AST_FEATURE_PLAY_WARNING
);
1605 if (ast_test_flag(peerflags
, OPT_CALLEE_TRANSFER
))
1606 ast_set_flag(&(config
.features_callee
), AST_FEATURE_REDIRECT
);
1607 if (ast_test_flag(peerflags
, OPT_CALLER_TRANSFER
))
1608 ast_set_flag(&(config
.features_caller
), AST_FEATURE_REDIRECT
);
1609 if (ast_test_flag(peerflags
, OPT_CALLEE_HANGUP
))
1610 ast_set_flag(&(config
.features_callee
), AST_FEATURE_DISCONNECT
);
1611 if (ast_test_flag(peerflags
, OPT_CALLER_HANGUP
))
1612 ast_set_flag(&(config
.features_caller
), AST_FEATURE_DISCONNECT
);
1613 if (ast_test_flag(peerflags
, OPT_CALLEE_MONITOR
))
1614 ast_set_flag(&(config
.features_callee
), AST_FEATURE_AUTOMON
);
1615 if (ast_test_flag(peerflags
, OPT_CALLER_MONITOR
))
1616 ast_set_flag(&(config
.features_caller
), AST_FEATURE_AUTOMON
);
1617 if (ast_test_flag(peerflags
, OPT_CALLEE_PARK
))
1618 ast_set_flag(&(config
.features_callee
), AST_FEATURE_PARKCALL
);
1619 if (ast_test_flag(peerflags
, OPT_CALLER_PARK
))
1620 ast_set_flag(&(config
.features_caller
), AST_FEATURE_PARKCALL
);
1622 config
.timelimit
= timelimit
;
1623 config
.play_warning
= play_warning
;
1624 config
.warning_freq
= warning_freq
;
1625 config
.warning_sound
= warning_sound
;
1626 config
.end_sound
= end_sound
;
1627 config
.start_sound
= start_sound
;
1631 } else if (sentringing
) {
1633 ast_indicate(chan
, -1);
1635 /* Be sure no generators are left on it */
1636 ast_deactivate_generator(chan
);
1637 /* Make sure channels are compatible */
1638 res
= ast_channel_make_compatible(chan
, peer
);
1640 ast_log(LOG_WARNING
, "Had to drop call because I couldn't make %s compatible with %s\n", chan
->name
, peer
->name
);
1645 if (opermode
&& (!strncmp(chan
->name
,"Zap",3)) &&
1646 (!strncmp(peer
->name
,"Zap",3)))
1648 struct oprmode oprmode
;
1650 oprmode
.peer
= peer
;
1651 oprmode
.mode
= opermode
;
1653 ast_channel_setoption(chan
,
1654 AST_OPTION_OPRMODE
,&oprmode
,sizeof(struct oprmode
),0);
1656 res
= ast_bridge_call(chan
,peer
,&config
);
1660 snprintf(toast
, sizeof(toast
), "%ld", (long)(end_time
- answer_time
));
1661 pbx_builtin_setvar_helper(chan
, "ANSWEREDTIME", toast
);
1669 snprintf(toast
, sizeof(toast
), "%ld", (long)(end_time
- start_time
));
1670 pbx_builtin_setvar_helper(chan
, "DIALEDTIME", toast
);
1673 if (res
!= AST_PBX_NO_HANGUP_PEER
) {
1674 if (!chan
->_softhangup
)
1675 chan
->hangupcause
= peer
->hangupcause
;
1683 } else if (sentringing
) {
1685 ast_indicate(chan
, -1);
1687 ast_rtp_early_bridge(chan
, NULL
);
1688 hanguptree(outgoing
, NULL
);
1689 pbx_builtin_setvar_helper(chan
, "DIALSTATUS", status
);
1691 ast_log(LOG_DEBUG
, "Exiting with DIALSTATUS=%s.\n", status
);
1693 if ((ast_test_flag(peerflags
, OPT_GO_ON
)) && (!chan
->_softhangup
) && (res
!= AST_PBX_KEEPALIVE
)) {
1694 if (calldurationlimit
)
1695 chan
->whentohangup
= 0;
1700 ast_module_user_remove(u
);
1704 static int dial_exec(struct ast_channel
*chan
, void *data
)
1706 struct ast_flags peerflags
;
1708 memset(&peerflags
, 0, sizeof(peerflags
));
1710 return dial_exec_full(chan
, data
, &peerflags
, NULL
);
1713 static int retrydial_exec(struct ast_channel
*chan
, void *data
)
1715 char *announce
= NULL
, *dialdata
= NULL
;
1716 const char *context
= NULL
;
1717 int sleep
= 0, loops
= 0, res
= -1;
1718 struct ast_module_user
*u
;
1719 struct ast_flags peerflags
;
1721 if (ast_strlen_zero(data
)) {
1722 ast_log(LOG_WARNING
, "RetryDial requires an argument!\n");
1726 u
= ast_module_user_add(chan
);
1728 announce
= ast_strdupa(data
);
1730 memset(&peerflags
, 0, sizeof(peerflags
));
1732 if ((dialdata
= strchr(announce
, '|'))) {
1734 if (sscanf(dialdata
, "%d", &sleep
) == 1) {
1737 ast_log(LOG_ERROR
, "%s requires the numerical argument <sleep>\n",rapp
);
1740 if ((dialdata
= strchr(dialdata
, '|'))) {
1742 if (sscanf(dialdata
, "%d", &loops
) != 1) {
1743 ast_log(LOG_ERROR
, "%s requires the numerical argument <loops>\n",rapp
);
1749 if ((dialdata
= strchr(dialdata
, '|'))) {
1752 ast_log(LOG_ERROR
, "%s requires more arguments\n",rapp
);
1760 loops
= -1; /* run forever */
1762 context
= pbx_builtin_getvar_helper(chan
, "EXITCONTEXT");
1768 chan
->data
= "Retrying";
1769 if (ast_test_flag(chan
, AST_FLAG_MOH
))
1772 res
= dial_exec_full(chan
, dialdata
, &peerflags
, &continue_exec
);
1777 if (ast_test_flag(&peerflags
, OPT_DTMF_EXIT
)) {
1778 if (!ast_strlen_zero(announce
)) {
1779 if (ast_fileexists(announce
, NULL
, chan
->language
) > 0) {
1780 if(!(res
= ast_streamfile(chan
, announce
, chan
->language
)))
1781 ast_waitstream(chan
, AST_DIGIT_ANY
);
1783 ast_log(LOG_WARNING
, "Announce file \"%s\" specified in Retrydial does not exist\n", announce
);
1785 if (!res
&& sleep
) {
1786 if (!ast_test_flag(chan
, AST_FLAG_MOH
))
1787 ast_moh_start(chan
, NULL
, NULL
);
1788 res
= ast_waitfordigit(chan
, sleep
);
1791 if (!ast_strlen_zero(announce
)) {
1792 if (ast_fileexists(announce
, NULL
, chan
->language
) > 0) {
1793 if (!(res
= ast_streamfile(chan
, announce
, chan
->language
)))
1794 res
= ast_waitstream(chan
, "");
1796 ast_log(LOG_WARNING
, "Announce file \"%s\" specified in Retrydial does not exist\n", announce
);
1799 if (!ast_test_flag(chan
, AST_FLAG_MOH
))
1800 ast_moh_start(chan
, NULL
, NULL
);
1802 res
= ast_waitfordigit(chan
, sleep
);
1809 else if (res
> 0) { /* Trying to send the call elsewhere (1 digit ext) */
1810 if (onedigit_goto(chan
, context
, (char) res
, 1)) {
1822 if (ast_test_flag(chan
, AST_FLAG_MOH
))
1825 ast_module_user_remove(u
);
1829 static int unload_module(void)
1833 res
= ast_unregister_application(app
);
1834 res
|= ast_unregister_application(rapp
);
1836 ast_module_user_hangup_all();
1841 static int load_module(void)
1845 res
= ast_register_application(app
, dial_exec
, synopsis
, descrip
);
1846 res
|= ast_register_application(rapp
, retrydial_exec
, rsynopsis
, rdescrip
);
1851 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY
, "Dialing Application");