Review Board 1.7.16


Allow app_dial to play 'indication tone while ringing' like 'option m' which will provide music on hold while ringing

Review Request #448 - Created Dec. 15, 2009 and submitted

Alec Davis
trunk
14504
Reviewers
asterisk-dev
Asterisk
This senario is based on an ETSI ISDN installation, but I'm sure applies to others.

option 'r' sends a Ringing Indication to the network, which informs the network we can deliver the call, but ultimately we may not be able to, and need to issue Congestion.
option 'm' sends a Progress Indication, which allows us to indicate Congestion and then let the call go, the network providor can then try the next provider.

The current ugly solution, is to record a music file, of Ringing, and play it, something like.
  exten => 80,1,Dial(DAHDI/2,30,m(myring))
  exten => 80,n,Congestion()

This patch provides an optional argument for option 'r' as in 'r(vodaring)'

Now a tidy and customizable way to play out any tones from the indications.conf file like.
  exten => 80,1,Dial(DAHDI/2,30,r(vodaring))
  exten => 80,n,Congestion()
100% test results with examples below.

exten => 80,1,Dial(DAHDI/2,,r(vodaring))
exten => 80,1,Dial(DAHDI/2,,r)
exten => 80,1,Dial(DAHDI/2,,m)
exten => 80,1,Dial(DAHDI/2,,)

Diff revision 3 (Latest)

1 2 3
1 2 3

  1. trunk/apps/app_dial.c: Loading...
trunk/apps/app_dial.c
Revision 235739 New Change
1
/*
1
/*
2
 * Asterisk -- An open source telephony toolkit.
2
 * Asterisk -- An open source telephony toolkit.
3
 *
3
 *
4
 * Copyright (C) 1999 - 2008, Digium, Inc.
4
 * Copyright (C) 1999 - 2008, Digium, Inc.
5
 *
5
 *
6
 * Mark Spencer <markster@digium.com>
6
 * Mark Spencer <markster@digium.com>
7
 *
7
 *
8
 * See http://www.asterisk.org for more information about
8
 * See http://www.asterisk.org for more information about
9
 * the Asterisk project. Please do not directly contact
9
 * the Asterisk project. Please do not directly contact
10
 * any of the maintainers of this project for assistance;
10
 * any of the maintainers of this project for assistance;
11
 * the project provides a web site, mailing lists and IRC
11
 * the project provides a web site, mailing lists and IRC
12
 * channels for your use.
12
 * channels for your use.
13
 *
13
 *
14
 * This program is free software, distributed under the terms of
14
 * This program is free software, distributed under the terms of
15
 * the GNU General Public License Version 2. See the LICENSE file
15
 * the GNU General Public License Version 2. See the LICENSE file
16
 * at the top of the source tree.
16
 * at the top of the source tree.
17
 */
17
 */
18

    
   
18

   
19
/*! \file
19
/*! \file
20
 *
20
 *
21
 * \brief dial() & retrydial() - Trivial application to dial a channel and send an URL on answer
21
 * \brief dial() & retrydial() - Trivial application to dial a channel and send an URL on answer
22
 *
22
 *
23
 * \author Mark Spencer <markster@digium.com>
23
 * \author Mark Spencer <markster@digium.com>
24
 *
24
 *
25
 * \ingroup applications
25
 * \ingroup applications
26
 */
26
 */
27

    
   
27

   
28
/*** MODULEINFO
28
/*** MODULEINFO
29
	<depend>chan_local</depend>
29
	<depend>chan_local</depend>
30
 ***/
30
 ***/
31

    
   
31

   
32

    
   
32

   
33
#include "asterisk.h"
33
#include "asterisk.h"
34

    
   
34

   
35
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
35
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
36

    
   
36

   
37
#include <sys/time.h>
37
#include <sys/time.h>
38
#include <sys/signal.h>
38
#include <sys/signal.h>
39
#include <sys/stat.h>
39
#include <sys/stat.h>
40
#include <netinet/in.h>
40
#include <netinet/in.h>
41

    
   
41

   
42
#include "asterisk/paths.h" /* use ast_config_AST_DATA_DIR */
42
#include "asterisk/paths.h" /* use ast_config_AST_DATA_DIR */
43
#include "asterisk/lock.h"
43
#include "asterisk/lock.h"
44
#include "asterisk/file.h"
44
#include "asterisk/file.h"
45
#include "asterisk/channel.h"
45
#include "asterisk/channel.h"
46
#include "asterisk/pbx.h"
46
#include "asterisk/pbx.h"
47
#include "asterisk/module.h"
47
#include "asterisk/module.h"
48
#include "asterisk/translate.h"
48
#include "asterisk/translate.h"
49
#include "asterisk/say.h"
49
#include "asterisk/say.h"
50
#include "asterisk/config.h"
50
#include "asterisk/config.h"
51
#include "asterisk/features.h"
51
#include "asterisk/features.h"
52
#include "asterisk/musiconhold.h"
52
#include "asterisk/musiconhold.h"
53
#include "asterisk/callerid.h"
53
#include "asterisk/callerid.h"
54
#include "asterisk/utils.h"
54
#include "asterisk/utils.h"
55
#include "asterisk/app.h"
55
#include "asterisk/app.h"
56
#include "asterisk/causes.h"
56
#include "asterisk/causes.h"
57
#include "asterisk/rtp_engine.h"
57
#include "asterisk/rtp_engine.h"
58
#include "asterisk/cdr.h"
58
#include "asterisk/cdr.h"
59
#include "asterisk/manager.h"
59
#include "asterisk/manager.h"
60
#include "asterisk/privacy.h"
60
#include "asterisk/privacy.h"
61
#include "asterisk/stringfields.h"
61
#include "asterisk/stringfields.h"
62
#include "asterisk/global_datastores.h"
62
#include "asterisk/global_datastores.h"
63
#include "asterisk/dsp.h"
63
#include "asterisk/dsp.h"
64
#include "asterisk/cel.h"
64
#include "asterisk/cel.h"

    
   
65
#include "asterisk/indications.h"
65

    
   
66

   
66
/*** DOCUMENTATION
67
/*** DOCUMENTATION
67
	<application name="Dial" language="en_US">
68
	<application name="Dial" language="en_US">
68
		<synopsis>
69
		<synopsis>
69
			Attempt to connect to another device or endpoint and bridge the call.
70
			Attempt to connect to another device or endpoint and bridge the call.
70
		</synopsis>
71
		</synopsis>
71
		<syntax>
72
		<syntax>
72
			<parameter name="Technology/Resource" required="true" argsep="&amp;">
73
			<parameter name="Technology/Resource" required="true" argsep="&amp;">
73
				<argument name="Technology/Resource" required="true">
74
				<argument name="Technology/Resource" required="true">
74
					<para>Specification of the device(s) to dial.  These must be in the format of
75
					<para>Specification of the device(s) to dial.  These must be in the format of
75
					<literal>Technology/Resource</literal>, where <replaceable>Technology</replaceable>
76
					<literal>Technology/Resource</literal>, where <replaceable>Technology</replaceable>
76
					represents a particular channel driver, and <replaceable>Resource</replaceable>
77
					represents a particular channel driver, and <replaceable>Resource</replaceable>
77
					represents a resource available to that particular channel driver.</para>
78
					represents a resource available to that particular channel driver.</para>
78
				</argument>
79
				</argument>
79
				<argument name="Technology2/Resource2" required="false" multiple="true">
80
				<argument name="Technology2/Resource2" required="false" multiple="true">
80
					<para>Optional extra devices to dial in parallel</para>
81
					<para>Optional extra devices to dial in parallel</para>
81
					<para>If you need more then one enter them as
82
					<para>If you need more then one enter them as
82
					Technology2/Resource2&amp;Technology3/Resourse3&amp;.....</para>
83
					Technology2/Resource2&amp;Technology3/Resourse3&amp;.....</para>
83
				</argument>
84
				</argument>
84
			</parameter>
85
			</parameter>
85
			<parameter name="timeout" required="false">
86
			<parameter name="timeout" required="false">
86
				<para>Specifies the number of seconds we attempt to dial the specified devices</para>
87
				<para>Specifies the number of seconds we attempt to dial the specified devices</para>
87
				<para>If not specified, this defaults to 136 years.</para>
88
				<para>If not specified, this defaults to 136 years.</para>
88
			</parameter>
89
			</parameter>
89
			<parameter name="options" required="false">
90
			<parameter name="options" required="false">
90
			   <optionlist>
91
			   <optionlist>
91
				<option name="A">
92
				<option name="A">
92
					<argument name="x" required="true">
93
					<argument name="x" required="true">
93
						<para>The file to play to the called party</para>
94
						<para>The file to play to the called party</para>
94
					</argument>
95
					</argument>
95
					<para>Play an announcement to the called party, where <replaceable>x</replaceable> is the prompt to be played</para>
96
					<para>Play an announcement to the called party, where <replaceable>x</replaceable> is the prompt to be played</para>
96
				</option>
97
				</option>
97
				<option name="a">
98
				<option name="a">
98
					<para>Immediately answer the calling channel when the called channel answers in
99
					<para>Immediately answer the calling channel when the called channel answers in
99
					all cases. Normally, the calling channel is answered when the called channel
100
					all cases. Normally, the calling channel is answered when the called channel
100
					answers, but when options such as A() and M() are used, the calling channel is
101
					answers, but when options such as A() and M() are used, the calling channel is
101
					not answered until all actions on the called channel (such as playing an
102
					not answered until all actions on the called channel (such as playing an
102
					announcement) are completed.  This option can be used to answer the calling
103
					announcement) are completed.  This option can be used to answer the calling
103
					channel before doing anything on the called channel. You will rarely need to use
104
					channel before doing anything on the called channel. You will rarely need to use
104
					this option, the default behavior is adequate in most cases.</para>
105
					this option, the default behavior is adequate in most cases.</para>
105
				</option>
106
				</option>
106
				<option name="C">
107
				<option name="C">
107
					<para>Reset the call detail record (CDR) for this call.</para>
108
					<para>Reset the call detail record (CDR) for this call.</para>
108
				</option>
109
				</option>
109
				<option name="c">
110
				<option name="c">
110
					<para>If the Dial() application cancels this call, always set the flag to tell the channel
111
					<para>If the Dial() application cancels this call, always set the flag to tell the channel
111
					driver that the call is answered elsewhere.</para>
112
					driver that the call is answered elsewhere.</para>
112
				</option>
113
				</option>
113
				<option name="d">
114
				<option name="d">
114
					<para>Allow the calling user to dial a 1 digit extension while waiting for
115
					<para>Allow the calling user to dial a 1 digit extension while waiting for
115
					a call to be answered. Exit to that extension if it exists in the
116
					a call to be answered. Exit to that extension if it exists in the
116
					current context, or the context defined in the <variable>EXITCONTEXT</variable> variable,
117
					current context, or the context defined in the <variable>EXITCONTEXT</variable> variable,
117
					if it exists.</para>
118
					if it exists.</para>
118
				</option>
119
				</option>
119
				<option name="D" argsep=":">
120
				<option name="D" argsep=":">
120
					<argument name="called" />
121
					<argument name="called" />
121
					<argument name="calling" />
122
					<argument name="calling" />
122
					<argument name="progress" />
123
					<argument name="progress" />
123
					<para>Send the specified DTMF strings <emphasis>after</emphasis> the called
124
					<para>Send the specified DTMF strings <emphasis>after</emphasis> the called
124
					party has answered, but before the call gets bridged. The 
125
					party has answered, but before the call gets bridged. The 
125
					<replaceable>called</replaceable> DTMF string is sent to the called party, and the 
126
					<replaceable>called</replaceable> DTMF string is sent to the called party, and the 
126
					<replaceable>calling</replaceable> DTMF string is sent to the calling party. Both arguments 
127
					<replaceable>calling</replaceable> DTMF string is sent to the calling party. Both arguments 
127
					can be used alone.  If <replaceable>progress</replaceable> is specified, its DTMF is sent
128
					can be used alone.  If <replaceable>progress</replaceable> is specified, its DTMF is sent
128
					immediately after receiving a PROGRESS message.</para>
129
					immediately after receiving a PROGRESS message.</para>
129
				</option>
130
				</option>
130
				<option name="e">
131
				<option name="e">
131
					<para>Execute the <literal>h</literal> extension for peer after the call ends</para>
132
					<para>Execute the <literal>h</literal> extension for peer after the call ends</para>
132
				</option>
133
				</option>
133
				<option name="f">
134
				<option name="f">
134
					<para>Force the callerid of the <emphasis>calling</emphasis> channel to be set as the
135
					<para>Force the callerid of the <emphasis>calling</emphasis> channel to be set as the
135
					extension associated with the channel using a dialplan <literal>hint</literal>.
136
					extension associated with the channel using a dialplan <literal>hint</literal>.
136
					For example, some PSTNs do not allow CallerID to be set to anything
137
					For example, some PSTNs do not allow CallerID to be set to anything
137
					other than the number assigned to the caller.</para>
138
					other than the number assigned to the caller.</para>
138
				</option>
139
				</option>
139
				<option name="F" argsep="^">
140
				<option name="F" argsep="^">
140
					<argument name="context" required="false" />
141
					<argument name="context" required="false" />
141
					<argument name="exten" required="false" />
142
					<argument name="exten" required="false" />
142
					<argument name="priority" required="true" />
143
					<argument name="priority" required="true" />
143
					<para>When the caller hangs up, transfer the called party
144
					<para>When the caller hangs up, transfer the called party
144
					to the specified destination and continue execution at that location.</para>
145
					to the specified destination and continue execution at that location.</para>
145
				</option>
146
				</option>
146
				<option name="F">
147
				<option name="F">
147
					<para>Proceed with dialplan execution at the next priority in the current extension if the
148
					<para>Proceed with dialplan execution at the next priority in the current extension if the
148
					source channel hangs up.</para>
149
					source channel hangs up.</para>
149
				</option>
150
				</option>
150
				<option name="g">
151
				<option name="g">
151
					<para>Proceed with dialplan execution at the next priority in the current extension if the
152
					<para>Proceed with dialplan execution at the next priority in the current extension if the
152
					destination channel hangs up.</para>
153
					destination channel hangs up.</para>
153
				</option>
154
				</option>
154
				<option name="G" argsep="^">
155
				<option name="G" argsep="^">
155
					<argument name="context" required="false" />
156
					<argument name="context" required="false" />
156
					<argument name="exten" required="false" />
157
					<argument name="exten" required="false" />
157
					<argument name="priority" required="true" />
158
					<argument name="priority" required="true" />
158
					<para>If the call is answered, transfer the calling party to
159
					<para>If the call is answered, transfer the calling party to
159
					the specified <replaceable>priority</replaceable> and the called party to the specified 
160
					the specified <replaceable>priority</replaceable> and the called party to the specified 
160
					<replaceable>priority</replaceable> plus one.</para>
161
					<replaceable>priority</replaceable> plus one.</para>
161
					<note>
162
					<note>
162
						<para>You cannot use any additional action post answer options in conjunction with this option.</para>
163
						<para>You cannot use any additional action post answer options in conjunction with this option.</para>
163
					</note>
164
					</note>
164
				</option>
165
				</option>
165
				<option name="h">
166
				<option name="h">
166
					<para>Allow the called party to hang up by sending the <literal>*</literal> DTMF digit.</para>
167
					<para>Allow the called party to hang up by sending the <literal>*</literal> DTMF digit.</para>
167
				</option>
168
				</option>
168
				<option name="H">
169
				<option name="H">
169
					<para>Allow the calling party to hang up by hitting the <literal>*</literal> DTMF digit.</para>
170
					<para>Allow the calling party to hang up by hitting the <literal>*</literal> DTMF digit.</para>
170
				</option>
171
				</option>
171
				<option name="i">
172
				<option name="i">
172
					<para>Asterisk will ignore any forwarding requests it may receive on this dial attempt.</para>
173
					<para>Asterisk will ignore any forwarding requests it may receive on this dial attempt.</para>
173
				</option>
174
				</option>
174
				<option name="I">
175
				<option name="I">
175
					<para>Asterisk will ignore any connected line update requests or redirecting party update
176
					<para>Asterisk will ignore any connected line update requests or redirecting party update
176
					requests it may receiveon this dial attempt.</para>
177
					requests it may receiveon this dial attempt.</para>
177
				</option>
178
				</option>
178
				<option name="k">
179
				<option name="k">
179
					<para>Allow the called party to enable parking of the call by sending
180
					<para>Allow the called party to enable parking of the call by sending
180
					the DTMF sequence defined for call parking in <filename>features.conf</filename>.</para>
181
					the DTMF sequence defined for call parking in <filename>features.conf</filename>.</para>
181
				</option>
182
				</option>
182
				<option name="K">
183
				<option name="K">
183
					<para>Allow the calling party to enable parking of the call by sending
184
					<para>Allow the calling party to enable parking of the call by sending
184
					the DTMF sequence defined for call parking in <filename>features.conf</filename>.</para>
185
					the DTMF sequence defined for call parking in <filename>features.conf</filename>.</para>
185
				</option>
186
				</option>
186
				<option name="L" argsep=":">
187
				<option name="L" argsep=":">
187
					<argument name="x" required="true">
188
					<argument name="x" required="true">
188
						<para>Maximum call time, in milliseconds</para>
189
						<para>Maximum call time, in milliseconds</para>
189
					</argument>
190
					</argument>
190
					<argument name="y">
191
					<argument name="y">
191
						<para>Warning time, in milliseconds</para>
192
						<para>Warning time, in milliseconds</para>
192
					</argument>
193
					</argument>
193
					<argument name="z">
194
					<argument name="z">
194
						<para>Repeat time, in milliseconds</para>
195
						<para>Repeat time, in milliseconds</para>
195
					</argument>
196
					</argument>
196
					<para>Limit the call to <replaceable>x</replaceable> milliseconds. Play a warning when <replaceable>y</replaceable> milliseconds are
197
					<para>Limit the call to <replaceable>x</replaceable> milliseconds. Play a warning when <replaceable>y</replaceable> milliseconds are
197
					left. Repeat the warning every <replaceable>z</replaceable> milliseconds until time expires.</para>
198
					left. Repeat the warning every <replaceable>z</replaceable> milliseconds until time expires.</para>
198
					<para>This option is affected by the following variables:</para>
199
					<para>This option is affected by the following variables:</para>
199
					<variablelist>
200
					<variablelist>
200
						<variable name="LIMIT_PLAYAUDIO_CALLER">
201
						<variable name="LIMIT_PLAYAUDIO_CALLER">
201
							<value name="yes" default="true" />
202
							<value name="yes" default="true" />
202
							<value name="no" />
203
							<value name="no" />
203
							<para>If set, this variable causes Asterisk to play the prompts to the caller.</para>
204
							<para>If set, this variable causes Asterisk to play the prompts to the caller.</para>
204
						</variable>
205
						</variable>
205
						<variable name="LIMIT_PLAYAUDIO_CALLEE">
206
						<variable name="LIMIT_PLAYAUDIO_CALLEE">
206
							<value name="yes" />
207
							<value name="yes" />
207
							<value name="no" default="true"/>
208
							<value name="no" default="true"/>
208
							<para>If set, this variable causes Asterisk to play the prompts to the callee.</para>
209
							<para>If set, this variable causes Asterisk to play the prompts to the callee.</para>
209
						</variable>
210
						</variable>
210
						<variable name="LIMIT_TIMEOUT_FILE">
211
						<variable name="LIMIT_TIMEOUT_FILE">
211
							<value name="filename"/>
212
							<value name="filename"/>
212
							<para>If specified, <replaceable>filename</replaceable> specifies the sound prompt to play when the timeout is reached.
213
							<para>If specified, <replaceable>filename</replaceable> specifies the sound prompt to play when the timeout is reached.
213
							If not set, the time remaining will be announced.</para>
214
							If not set, the time remaining will be announced.</para>
214
						</variable>
215
						</variable>
215
						<variable name="LIMIT_CONNECT_FILE">
216
						<variable name="LIMIT_CONNECT_FILE">
216
							<value name="filename"/>
217
							<value name="filename"/>
217
							<para>If specified, <replaceable>filename</replaceable> specifies the sound prompt to play when the call begins.
218
							<para>If specified, <replaceable>filename</replaceable> specifies the sound prompt to play when the call begins.
218
							If not set, the time remaining will be announced.</para>
219
							If not set, the time remaining will be announced.</para>
219
						</variable>
220
						</variable>
220
						<variable name="LIMIT_WARNING_FILE">
221
						<variable name="LIMIT_WARNING_FILE">
221
							<value name="filename"/>
222
							<value name="filename"/>
222
							<para>If specified, <replaceable>filename</replaceable> specifies the sound prompt to play as
223
							<para>If specified, <replaceable>filename</replaceable> specifies the sound prompt to play as
223
							a warning when time <replaceable>x</replaceable> is reached. If not set, the time remaining will be announced.</para>
224
							a warning when time <replaceable>x</replaceable> is reached. If not set, the time remaining will be announced.</para>
224
						</variable>
225
						</variable>
225
					</variablelist>
226
					</variablelist>
226
				</option>
227
				</option>
227
				<option name="m">
228
				<option name="m">
228
					<argument name="class" required="false"/>
229
					<argument name="class" required="false"/>
229
					<para>Provide hold music to the calling party until a requested
230
					<para>Provide hold music to the calling party until a requested
230
					channel answers. A specific music on hold <replaceable>class</replaceable>
231
					channel answers. A specific music on hold <replaceable>class</replaceable>
231
					(as defined in <filename>musiconhold.conf</filename>) can be specified.</para>
232
					(as defined in <filename>musiconhold.conf</filename>) can be specified.</para>
232
				</option>
233
				</option>
233
				<option name="M" argsep="^">
234
				<option name="M" argsep="^">
234
					<argument name="macro" required="true">
235
					<argument name="macro" required="true">
235
						<para>Name of the macro that should be executed.</para>
236
						<para>Name of the macro that should be executed.</para>
236
					</argument>
237
					</argument>
237
					<argument name="arg" multiple="true">
238
					<argument name="arg" multiple="true">
238
						<para>Macro arguments</para>
239
						<para>Macro arguments</para>
239
					</argument>
240
					</argument>
240
					<para>Execute the specified <replaceable>macro</replaceable> for the <emphasis>called</emphasis> channel 
241
					<para>Execute the specified <replaceable>macro</replaceable> for the <emphasis>called</emphasis> channel 
241
					before connecting to the calling channel. Arguments can be specified to the Macro
242
					before connecting to the calling channel. Arguments can be specified to the Macro
242
					using <literal>^</literal> as a delimiter. The macro can set the variable
243
					using <literal>^</literal> as a delimiter. The macro can set the variable
243
					<variable>MACRO_RESULT</variable> to specify the following actions after the macro is
244
					<variable>MACRO_RESULT</variable> to specify the following actions after the macro is
244
					finished executing:</para>
245
					finished executing:</para>
245
					<variablelist>
246
					<variablelist>
246
						<variable name="MACRO_RESULT">
247
						<variable name="MACRO_RESULT">
247
							<para>If set, this action will be taken after the macro finished executing.</para>
248
							<para>If set, this action will be taken after the macro finished executing.</para>
248
							<value name="ABORT">
249
							<value name="ABORT">
249
								Hangup both legs of the call
250
								Hangup both legs of the call
250
							</value>
251
							</value>
251
							<value name="CONGESTION">
252
							<value name="CONGESTION">
252
								Behave as if line congestion was encountered
253
								Behave as if line congestion was encountered
253
							</value>
254
							</value>
254
							<value name="BUSY">
255
							<value name="BUSY">
255
								Behave as if a busy signal was encountered
256
								Behave as if a busy signal was encountered
256
							</value>
257
							</value>
257
							<value name="CONTINUE">
258
							<value name="CONTINUE">
258
								Hangup the called party and allow the calling party to continue dialplan execution at the next priority
259
								Hangup the called party and allow the calling party to continue dialplan execution at the next priority
259
							</value>
260
							</value>
260
							<!-- TODO: Fix this syntax up, once we've figured out how to specify the GOTO syntax -->
261
							<!-- TODO: Fix this syntax up, once we've figured out how to specify the GOTO syntax -->
261
							<value name="GOTO:&lt;context&gt;^&lt;exten&gt;^&lt;priority&gt;">
262
							<value name="GOTO:&lt;context&gt;^&lt;exten&gt;^&lt;priority&gt;">
262
								Transfer the call to the specified destination.
263
								Transfer the call to the specified destination.
263
							</value>
264
							</value>
264
						</variable>
265
						</variable>
265
					</variablelist>
266
					</variablelist>
266
					<note>
267
					<note>
267
						<para>You cannot use any additional action post answer options in conjunction
268
						<para>You cannot use any additional action post answer options in conjunction
268
						with this option. Also, pbx services are not run on the peer (called) channel,
269
						with this option. Also, pbx services are not run on the peer (called) channel,
269
						so you will not be able to set timeouts via the TIMEOUT() function in this macro.</para>
270
						so you will not be able to set timeouts via the TIMEOUT() function in this macro.</para>
270
					</note>
271
					</note>
271
					<warning><para>Be aware of the limitations that macros have, specifically with regards to use of
272
					<warning><para>Be aware of the limitations that macros have, specifically with regards to use of
272
					the <literal>WaitExten</literal> application. For more information, see the documentation for
273
					the <literal>WaitExten</literal> application. For more information, see the documentation for
273
					Macro()</para></warning>
274
					Macro()</para></warning>
274
				</option>
275
				</option>
275
				<option name="n">
276
				<option name="n">
276
				        <argument name="delete">
277
				        <argument name="delete">
277
					        <para>With <replaceable>delete</replaceable> either not specified or set to <literal>0</literal>,
278
					        <para>With <replaceable>delete</replaceable> either not specified or set to <literal>0</literal>,
278
						the recorded introduction will not be deleted if the caller hangs up while the remote party has not
279
						the recorded introduction will not be deleted if the caller hangs up while the remote party has not
279
						yet answered.</para>
280
						yet answered.</para>
280
						<para>With <replaceable>delete</replaceable> set to <literal>1</literal>, the introduction will
281
						<para>With <replaceable>delete</replaceable> set to <literal>1</literal>, the introduction will
281
						always be deleted.</para>
282
						always be deleted.</para>
282
					</argument>
283
					</argument>
283
					<para>This option is a modifier for the call screening/privacy mode. (See the 
284
					<para>This option is a modifier for the call screening/privacy mode. (See the 
284
					<literal>p</literal> and <literal>P</literal> options.) It specifies
285
					<literal>p</literal> and <literal>P</literal> options.) It specifies
285
					that no introductions are to be saved in the <directory>priv-callerintros</directory>
286
					that no introductions are to be saved in the <directory>priv-callerintros</directory>
286
					directory.</para>
287
					directory.</para>
287
				</option>
288
				</option>
288
				<option name="N">
289
				<option name="N">
289
					<para>This option is a modifier for the call screening/privacy mode. It specifies
290
					<para>This option is a modifier for the call screening/privacy mode. It specifies
290
					that if Caller*ID is present, do not screen the call.</para>
291
					that if Caller*ID is present, do not screen the call.</para>
291
				</option>
292
				</option>
292
				<option name="o">
293
				<option name="o">
293
					<para>Specify that the Caller*ID that was present on the <emphasis>calling</emphasis> channel
294
					<para>Specify that the Caller*ID that was present on the <emphasis>calling</emphasis> channel
294
					be set as the Caller*ID on the <emphasis>called</emphasis> channel. This was the
295
					be set as the Caller*ID on the <emphasis>called</emphasis> channel. This was the
295
					behavior of Asterisk 1.0 and earlier.</para>
296
					behavior of Asterisk 1.0 and earlier.</para>
296
				</option>
297
				</option>
297
				<option name="O">
298
				<option name="O">
298
					<argument name="mode">
299
					<argument name="mode">
299
						<para>With <replaceable>mode</replaceable> either not specified or set to <literal>1</literal>,
300
						<para>With <replaceable>mode</replaceable> either not specified or set to <literal>1</literal>,
300
						the originator hanging up will cause the phone to ring back immediately.</para>
301
						the originator hanging up will cause the phone to ring back immediately.</para>
301
						<para>With <replaceable>mode</replaceable> set to <literal>2</literal>, when the operator 
302
						<para>With <replaceable>mode</replaceable> set to <literal>2</literal>, when the operator 
302
						flashes the trunk, it will ring their phone back.</para>
303
						flashes the trunk, it will ring their phone back.</para>
303
					</argument>
304
					</argument>
304
					<para>Enables <emphasis>operator services</emphasis> mode.  This option only
305
					<para>Enables <emphasis>operator services</emphasis> mode.  This option only
305
					works when bridging a DAHDI channel to another DAHDI channel
306
					works when bridging a DAHDI channel to another DAHDI channel
306
					only. if specified on non-DAHDI interfaces, it will be ignored.
307
					only. if specified on non-DAHDI interfaces, it will be ignored.
307
					When the destination answers (presumably an operator services
308
					When the destination answers (presumably an operator services
308
					station), the originator no longer has control of their line.
309
					station), the originator no longer has control of their line.
309
					They may hang up, but the switch will not release their line
310
					They may hang up, but the switch will not release their line
310
					until the destination party (the operator) hangs up.</para>
311
					until the destination party (the operator) hangs up.</para>
311
				</option>
312
				</option>
312
				<option name="p">
313
				<option name="p">
313
					<para>This option enables screening mode. This is basically Privacy mode
314
					<para>This option enables screening mode. This is basically Privacy mode
314
					without memory.</para>
315
					without memory.</para>
315
				</option>
316
				</option>
316
				<option name="P">
317
				<option name="P">
317
					<argument name="x" />
318
					<argument name="x" />
318
					<para>Enable privacy mode. Use <replaceable>x</replaceable> as the family/key in the AstDB database if
319
					<para>Enable privacy mode. Use <replaceable>x</replaceable> as the family/key in the AstDB database if
319
					it is provided. The current extension is used if a database family/key is not specified.</para>
320
					it is provided. The current extension is used if a database family/key is not specified.</para>
320
				</option>
321
				</option>
321
				<option name="r">
322
				<option name="r">
322
					<para>Indicate ringing to the calling party, even if the called party isn't actually ringing. Pass no audio to the calling
323
					<para>Default: Indicate ringing to the calling party, even if the called party isn't actually ringing. Pass no audio to the calling
323
					party until the called channel has answered.</para>
324
					party until the called channel has answered.</para>

    
   
325
					<argument name="tone" required="false">

    
   
326
						<para>Indicate progress to calling party. Send audio 'tone' from indications.conf</para>

    
   
327
					</argument>
324
				</option>
328
				</option>
325
				<option name="S">
329
				<option name="S">
326
					<argument name="x" required="true" />
330
					<argument name="x" required="true" />
327
					<para>Hang up the call <replaceable>x</replaceable> seconds <emphasis>after</emphasis> the called party has
331
					<para>Hang up the call <replaceable>x</replaceable> seconds <emphasis>after</emphasis> the called party has
328
					answered the call.</para>
332
					answered the call.</para>
329
				</option>
333
				</option>
330
				<option name="t">
334
				<option name="t">
331
					<para>Allow the called party to transfer the calling party by sending the
335
					<para>Allow the called party to transfer the calling party by sending the
332
					DTMF sequence defined in <filename>features.conf</filename>.</para>
336
					DTMF sequence defined in <filename>features.conf</filename>.</para>
333
				</option>
337
				</option>
334
				<option name="T">
338
				<option name="T">
335
					<para>Allow the calling party to transfer the called party by sending the
339
					<para>Allow the calling party to transfer the called party by sending the
336
					DTMF sequence defined in <filename>features.conf</filename>.</para>
340
					DTMF sequence defined in <filename>features.conf</filename>.</para>
337
				</option>
341
				</option>
338
				<option name="U" argsep="^">
342
				<option name="U" argsep="^">
339
					<argument name="x" required="true">
343
					<argument name="x" required="true">
340
						<para>Name of the subroutine to execute via Gosub</para>
344
						<para>Name of the subroutine to execute via Gosub</para>
341
					</argument>
345
					</argument>
342
					<argument name="arg" multiple="true" required="false">
346
					<argument name="arg" multiple="true" required="false">
343
						<para>Arguments for the Gosub routine</para>
347
						<para>Arguments for the Gosub routine</para>
344
					</argument>
348
					</argument>
345
					<para>Execute via Gosub the routine <replaceable>x</replaceable> for the <emphasis>called</emphasis> channel before connecting
349
					<para>Execute via Gosub the routine <replaceable>x</replaceable> for the <emphasis>called</emphasis> channel before connecting
346
					to the calling channel. Arguments can be specified to the Gosub
350
					to the calling channel. Arguments can be specified to the Gosub
347
					using <literal>^</literal> as a delimiter. The Gosub routine can set the variable
351
					using <literal>^</literal> as a delimiter. The Gosub routine can set the variable
348
					<variable>GOSUB_RESULT</variable> to specify the following actions after the Gosub returns.</para>
352
					<variable>GOSUB_RESULT</variable> to specify the following actions after the Gosub returns.</para>
349
					<variablelist>
353
					<variablelist>
350
						<variable name="GOSUB_RESULT">
354
						<variable name="GOSUB_RESULT">
351
							<value name="ABORT">
355
							<value name="ABORT">
352
								Hangup both legs of the call.
356
								Hangup both legs of the call.
353
							</value>
357
							</value>
354
							<value name="CONGESTION">
358
							<value name="CONGESTION">
355
								Behave as if line congestion was encountered.
359
								Behave as if line congestion was encountered.
356
							</value>
360
							</value>
357
							<value name="BUSY">
361
							<value name="BUSY">
358
								Behave as if a busy signal was encountered.
362
								Behave as if a busy signal was encountered.
359
							</value>
363
							</value>
360
							<value name="CONTINUE">
364
							<value name="CONTINUE">
361
								Hangup the called party and allow the calling party
365
								Hangup the called party and allow the calling party
362
								to continue dialplan execution at the next priority.
366
								to continue dialplan execution at the next priority.
363
							</value>
367
							</value>
364
							<!-- TODO: Fix this syntax up, once we've figured out how to specify the GOTO syntax -->
368
							<!-- TODO: Fix this syntax up, once we've figured out how to specify the GOTO syntax -->
365
							<value name="GOTO:&lt;context&gt;^&lt;exten&gt;^&lt;priority&gt;">
369
							<value name="GOTO:&lt;context&gt;^&lt;exten&gt;^&lt;priority&gt;">
366
								Transfer the call to the specified priority. Optionally, an extension, or
370
								Transfer the call to the specified priority. Optionally, an extension, or
367
								extension and priority can be specified.
371
								extension and priority can be specified.
368
							</value>
372
							</value>
369
						</variable>
373
						</variable>
370
					</variablelist>
374
					</variablelist>
371
					<note>
375
					<note>
372
						<para>You cannot use any additional action post answer options in conjunction
376
						<para>You cannot use any additional action post answer options in conjunction
373
						with this option. Also, pbx services are not run on the peer (called) channel,
377
						with this option. Also, pbx services are not run on the peer (called) channel,
374
						so you will not be able to set timeouts via the TIMEOUT() function in this routine.</para>
378
						so you will not be able to set timeouts via the TIMEOUT() function in this routine.</para>
375
					</note>
379
					</note>
376
				</option>
380
				</option>
377
				<option name="w">
381
				<option name="w">
378
					<para>Allow the called party to enable recording of the call by sending
382
					<para>Allow the called party to enable recording of the call by sending
379
					the DTMF sequence defined for one-touch recording in <filename>features.conf</filename>.</para>
383
					the DTMF sequence defined for one-touch recording in <filename>features.conf</filename>.</para>
380
				</option>
384
				</option>
381
				<option name="W">
385
				<option name="W">
382
					<para>Allow the calling party to enable recording of the call by sending
386
					<para>Allow the calling party to enable recording of the call by sending
383
					the DTMF sequence defined for one-touch recording in <filename>features.conf</filename>.</para>
387
					the DTMF sequence defined for one-touch recording in <filename>features.conf</filename>.</para>
384
				</option>
388
				</option>
385
				<option name="x">
389
				<option name="x">
386
					<para>Allow the called party to enable recording of the call by sending
390
					<para>Allow the called party to enable recording of the call by sending
387
					the DTMF sequence defined for one-touch automixmonitor in <filename>features.conf</filename>.</para>
391
					the DTMF sequence defined for one-touch automixmonitor in <filename>features.conf</filename>.</para>
388
				</option>
392
				</option>
389
				<option name="X">
393
				<option name="X">
390
					<para>Allow the calling party to enable recording of the call by sending
394
					<para>Allow the calling party to enable recording of the call by sending
391
					the DTMF sequence defined for one-touch automixmonitor in <filename>features.conf</filename>.</para>
395
					the DTMF sequence defined for one-touch automixmonitor in <filename>features.conf</filename>.</para>
392
				</option>
396
				</option>
393
				<option name="z">
397
				<option name="z">
394
					<para>On a call forward, cancel any dial timeout which has been set for this call.</para>
398
					<para>On a call forward, cancel any dial timeout which has been set for this call.</para>
395
				</option>
399
				</option>
396
				</optionlist>
400
				</optionlist>
397
			</parameter>
401
			</parameter>
398
			<parameter name="URL">
402
			<parameter name="URL">
399
				<para>The optional URL will be sent to the called party if the channel driver supports it.</para>
403
				<para>The optional URL will be sent to the called party if the channel driver supports it.</para>
400
			</parameter>
404
			</parameter>
401
		</syntax>
405
		</syntax>
402
		<description>
406
		<description>
403
			<para>This application will place calls to one or more specified channels. As soon
407
			<para>This application will place calls to one or more specified channels. As soon
404
			as one of the requested channels answers, the originating channel will be
408
			as one of the requested channels answers, the originating channel will be
405
			answered, if it has not already been answered. These two channels will then
409
			answered, if it has not already been answered. These two channels will then
406
			be active in a bridged call. All other channels that were requested will then
410
			be active in a bridged call. All other channels that were requested will then
407
			be hung up.</para>
411
			be hung up.</para>
408

    
   
412

   
409
			<para>Unless there is a timeout specified, the Dial application will wait
413
			<para>Unless there is a timeout specified, the Dial application will wait
410
			indefinitely until one of the called channels answers, the user hangs up, or
414
			indefinitely until one of the called channels answers, the user hangs up, or
411
			if all of the called channels are busy or unavailable. Dialplan executing will
415
			if all of the called channels are busy or unavailable. Dialplan executing will
412
			continue if no requested channels can be called, or if the timeout expires.
416
			continue if no requested channels can be called, or if the timeout expires.
413
			This application will report normal termination if the originating channel
417
			This application will report normal termination if the originating channel
414
			hangs up, or if the call is bridged and either of the parties in the bridge
418
			hangs up, or if the call is bridged and either of the parties in the bridge
415
			ends the call.</para>
419
			ends the call.</para>
416
			<para>If the <variable>OUTBOUND_GROUP</variable> variable is set, all peer channels created by this
420
			<para>If the <variable>OUTBOUND_GROUP</variable> variable is set, all peer channels created by this
417
			application will be put into that group (as in Set(GROUP()=...).
421
			application will be put into that group (as in Set(GROUP()=...).
418
			If the <variable>OUTBOUND_GROUP_ONCE</variable> variable is set, all peer channels created by this
422
			If the <variable>OUTBOUND_GROUP_ONCE</variable> variable is set, all peer channels created by this
419
			application will be put into that group (as in Set(GROUP()=...). Unlike OUTBOUND_GROUP,
423
			application will be put into that group (as in Set(GROUP()=...). Unlike OUTBOUND_GROUP,
420
			however, the variable will be unset after use.</para>
424
			however, the variable will be unset after use.</para>
421

    
   
425

   
422
			<para>This application sets the following channel variables:</para>
426
			<para>This application sets the following channel variables:</para>
423
			<variablelist>
427
			<variablelist>
424
				<variable name="DIALEDTIME">
428
				<variable name="DIALEDTIME">
425
					<para>This is the time from dialing a channel until when it is disconnected.</para>
429
					<para>This is the time from dialing a channel until when it is disconnected.</para>
426
				</variable>
430
				</variable>
427
				<variable name="ANSWEREDTIME">
431
				<variable name="ANSWEREDTIME">
428
					<para>This is the amount of time for actual call.</para>
432
					<para>This is the amount of time for actual call.</para>
429
				</variable>
433
				</variable>
430
				<variable name="DIALSTATUS">
434
				<variable name="DIALSTATUS">
431
					<para>This is the status of the call</para>
435
					<para>This is the status of the call</para>
432
					<value name="CHANUNAVAIL" />
436
					<value name="CHANUNAVAIL" />
433
					<value name="CONGESTION" />
437
					<value name="CONGESTION" />
434
					<value name="NOANSWER" />
438
					<value name="NOANSWER" />
435
					<value name="BUSY" />
439
					<value name="BUSY" />
436
					<value name="ANSWER" />
440
					<value name="ANSWER" />
437
					<value name="CANCEL" />
441
					<value name="CANCEL" />
438
					<value name="DONTCALL">
442
					<value name="DONTCALL">
439
						For the Privacy and Screening Modes.
443
						For the Privacy and Screening Modes.
440
						Will be set if the called party chooses to send the calling party to the 'Go Away' script.
444
						Will be set if the called party chooses to send the calling party to the 'Go Away' script.
441
					</value>
445
					</value>
442
					<value name="TORTURE">
446
					<value name="TORTURE">
443
						For the Privacy and Screening Modes.
447
						For the Privacy and Screening Modes.
444
						Will be set if the called party chooses to send the calling party to the 'torture' script.
448
						Will be set if the called party chooses to send the calling party to the 'torture' script.
445
					</value>
449
					</value>
446
					<value name="INVALIDARGS" />
450
					<value name="INVALIDARGS" />
447
				</variable>
451
				</variable>
448
			</variablelist>
452
			</variablelist>
449
		</description>
453
		</description>
450
	</application>
454
	</application>
451
	<application name="RetryDial" language="en_US">
455
	<application name="RetryDial" language="en_US">
452
		<synopsis>
456
		<synopsis>
453
			Place a call, retrying on failure allowing an optional exit extension.
457
			Place a call, retrying on failure allowing an optional exit extension.
454
		</synopsis>
458
		</synopsis>
455
		<syntax>
459
		<syntax>
456
			<parameter name="announce" required="true">
460
			<parameter name="announce" required="true">
457
				<para>Filename of sound that will be played when no channel can be reached</para>
461
				<para>Filename of sound that will be played when no channel can be reached</para>
458
			</parameter>
462
			</parameter>
459
			<parameter name="sleep" required="true">
463
			<parameter name="sleep" required="true">
460
				<para>Number of seconds to wait after a dial attempt failed before a new attempt is made</para>
464
				<para>Number of seconds to wait after a dial attempt failed before a new attempt is made</para>
461
			</parameter>
465
			</parameter>
462
			<parameter name="retries" required="true">
466
			<parameter name="retries" required="true">
463
				<para>Number of retries</para>
467
				<para>Number of retries</para>
464
				<para>When this is reached flow will continue at the next priority in the dialplan</para>
468
				<para>When this is reached flow will continue at the next priority in the dialplan</para>
465
			</parameter>
469
			</parameter>
466
			<parameter name="dialargs" required="true">
470
			<parameter name="dialargs" required="true">
467
				<para>Same format as arguments provided to the Dial application</para>
471
				<para>Same format as arguments provided to the Dial application</para>
468
			</parameter>
472
			</parameter>
469
		</syntax>
473
		</syntax>
470
		<description>
474
		<description>
471
			<para>This application will attempt to place a call using the normal Dial application.
475
			<para>This application will attempt to place a call using the normal Dial application.
472
			If no channel can be reached, the <replaceable>announce</replaceable> file will be played.
476
			If no channel can be reached, the <replaceable>announce</replaceable> file will be played.
473
			Then, it will wait <replaceable>sleep</replaceable> number of seconds before retrying the call.
477
			Then, it will wait <replaceable>sleep</replaceable> number of seconds before retrying the call.
474
			After <replaceable>retries</replaceable> number of attempts, the calling channel will continue at the next priority in the dialplan.
478
			After <replaceable>retries</replaceable> number of attempts, the calling channel will continue at the next priority in the dialplan.
475
			If the <replaceable>retries</replaceable> setting is set to 0, this application will retry endlessly.
479
			If the <replaceable>retries</replaceable> setting is set to 0, this application will retry endlessly.
476
			While waiting to retry a call, a 1 digit extension may be dialed. If that
480
			While waiting to retry a call, a 1 digit extension may be dialed. If that
477
			extension exists in either the context defined in <variable>EXITCONTEXT</variable> or the current
481
			extension exists in either the context defined in <variable>EXITCONTEXT</variable> or the current
478
			one, The call will jump to that extension immediately.
482
			one, The call will jump to that extension immediately.
479
			The <replaceable>dialargs</replaceable> are specified in the same format that arguments are provided
483
			The <replaceable>dialargs</replaceable> are specified in the same format that arguments are provided
480
			to the Dial application.</para>
484
			to the Dial application.</para>
481
		</description>
485
		</description>
482
	</application>
486
	</application>
483
 ***/
487
 ***/
484

    
   
488

   
485
static const char app[] = "Dial";
489
static const char app[] = "Dial";
486
static const char rapp[] = "RetryDial";
490
static const char rapp[] = "RetryDial";
487

    
   
491

   
488
enum {
492
enum {
489
	OPT_ANNOUNCE =          (1 << 0),
493
	OPT_ANNOUNCE =          (1 << 0),
490
	OPT_RESETCDR =          (1 << 1),
494
	OPT_RESETCDR =          (1 << 1),
491
	OPT_DTMF_EXIT =         (1 << 2),
495
	OPT_DTMF_EXIT =         (1 << 2),
492
	OPT_SENDDTMF =          (1 << 3),
496
	OPT_SENDDTMF =          (1 << 3),
493
	OPT_FORCECLID =         (1 << 4),
497
	OPT_FORCECLID =         (1 << 4),
494
	OPT_GO_ON =             (1 << 5),
498
	OPT_GO_ON =             (1 << 5),
495
	OPT_CALLEE_HANGUP =     (1 << 6),
499
	OPT_CALLEE_HANGUP =     (1 << 6),
496
	OPT_CALLER_HANGUP =     (1 << 7),
500
	OPT_CALLER_HANGUP =     (1 << 7),
497
	OPT_ORIGINAL_CLID =     (1 << 8),
501
	OPT_ORIGINAL_CLID =     (1 << 8),
498
	OPT_DURATION_LIMIT =    (1 << 9),
502
	OPT_DURATION_LIMIT =    (1 << 9),
499
	OPT_MUSICBACK =         (1 << 10),
503
	OPT_MUSICBACK =         (1 << 10),
500
	OPT_CALLEE_MACRO =      (1 << 11),
504
	OPT_CALLEE_MACRO =      (1 << 11),
501
	OPT_SCREEN_NOINTRO =    (1 << 12),
505
	OPT_SCREEN_NOINTRO =    (1 << 12),
502
	OPT_SCREEN_NOCALLERID = (1 << 13),
506
	OPT_SCREEN_NOCALLERID = (1 << 13),
503
	OPT_IGNORE_CONNECTEDLINE = (1 << 14),
507
	OPT_IGNORE_CONNECTEDLINE = (1 << 14),
504
	OPT_SCREENING =         (1 << 15),
508
	OPT_SCREENING =         (1 << 15),
505
	OPT_PRIVACY =           (1 << 16),
509
	OPT_PRIVACY =           (1 << 16),
506
	OPT_RINGBACK =          (1 << 17),
510
	OPT_RINGBACK =          (1 << 17),
507
	OPT_DURATION_STOP =     (1 << 18),
511
	OPT_DURATION_STOP =     (1 << 18),
508
	OPT_CALLEE_TRANSFER =   (1 << 19),
512
	OPT_CALLEE_TRANSFER =   (1 << 19),
509
	OPT_CALLER_TRANSFER =   (1 << 20),
513
	OPT_CALLER_TRANSFER =   (1 << 20),
510
	OPT_CALLEE_MONITOR =    (1 << 21),
514
	OPT_CALLEE_MONITOR =    (1 << 21),
511
	OPT_CALLER_MONITOR =    (1 << 22),
515
	OPT_CALLER_MONITOR =    (1 << 22),
512
	OPT_GOTO =              (1 << 23),
516
	OPT_GOTO =              (1 << 23),
513
	OPT_OPERMODE =          (1 << 24),
517
	OPT_OPERMODE =          (1 << 24),
514
	OPT_CALLEE_PARK =       (1 << 25),
518
	OPT_CALLEE_PARK =       (1 << 25),
515
	OPT_CALLER_PARK =       (1 << 26),
519
	OPT_CALLER_PARK =       (1 << 26),
516
	OPT_IGNORE_FORWARDING = (1 << 27),
520
	OPT_IGNORE_FORWARDING = (1 << 27),
517
	OPT_CALLEE_GOSUB =      (1 << 28),
521
	OPT_CALLEE_GOSUB =      (1 << 28),
518
	OPT_CALLEE_MIXMONITOR = (1 << 29),
522
	OPT_CALLEE_MIXMONITOR = (1 << 29),
519
	OPT_CALLER_MIXMONITOR = (1 << 30),
523
	OPT_CALLER_MIXMONITOR = (1 << 30),
520
	OPT_CALLER_ANSWER =	(1 << 31),
524
	OPT_CALLER_ANSWER =	(1 << 31),
521
};
525
};
522

    
   
526

   
523
#define DIAL_STILLGOING      (1 << 31)
527
#define DIAL_STILLGOING      (1 << 31)
524
#define DIAL_NOFORWARDHTML   ((uint64_t)1 << 32) /* flags are now 64 bits, so keep it up! */
528
#define DIAL_NOFORWARDHTML   ((uint64_t)1 << 32) /* flags are now 64 bits, so keep it up! */
525
#define DIAL_NOCONNECTEDLINE ((uint64_t)1 << 33)
529
#define DIAL_NOCONNECTEDLINE ((uint64_t)1 << 33)
526
#define OPT_CANCEL_ELSEWHERE ((uint64_t)1 << 34)
530
#define OPT_CANCEL_ELSEWHERE ((uint64_t)1 << 34)
527
#define OPT_PEER_H           ((uint64_t)1 << 35)
531
#define OPT_PEER_H           ((uint64_t)1 << 35)
528
#define OPT_CALLEE_GO_ON     ((uint64_t)1 << 36)
532
#define OPT_CALLEE_GO_ON     ((uint64_t)1 << 36)
529
#define OPT_CANCEL_TIMEOUT   ((uint64_t)1 << 37)
533
#define OPT_CANCEL_TIMEOUT   ((uint64_t)1 << 37)
530

    
   
534

   
531
enum {
535
enum {
532
	OPT_ARG_ANNOUNCE = 0,
536
	OPT_ARG_ANNOUNCE = 0,
533
	OPT_ARG_SENDDTMF,
537
	OPT_ARG_SENDDTMF,
534
	OPT_ARG_GOTO,
538
	OPT_ARG_GOTO,
535
	OPT_ARG_DURATION_LIMIT,
539
	OPT_ARG_DURATION_LIMIT,
536
	OPT_ARG_MUSICBACK,
540
	OPT_ARG_MUSICBACK,
537
	OPT_ARG_CALLEE_MACRO,
541
	OPT_ARG_CALLEE_MACRO,

    
   
542
	OPT_ARG_RINGBACK,
538
	OPT_ARG_CALLEE_GOSUB,
543
	OPT_ARG_CALLEE_GOSUB,
539
	OPT_ARG_CALLEE_GO_ON,
544
	OPT_ARG_CALLEE_GO_ON,
540
	OPT_ARG_PRIVACY,
545
	OPT_ARG_PRIVACY,
541
	OPT_ARG_DURATION_STOP,
546
	OPT_ARG_DURATION_STOP,
542
	OPT_ARG_OPERMODE,
547
	OPT_ARG_OPERMODE,
543
	OPT_ARG_SCREEN_NOINTRO,
548
	OPT_ARG_SCREEN_NOINTRO,
544
	/* note: this entry _MUST_ be the last one in the enum */
549
	/* note: this entry _MUST_ be the last one in the enum */
545
	OPT_ARG_ARRAY_SIZE,
550
	OPT_ARG_ARRAY_SIZE,
546
};
551
};
547

    
   
552

   
548
AST_APP_OPTIONS(dial_exec_options, BEGIN_OPTIONS
553
AST_APP_OPTIONS(dial_exec_options, BEGIN_OPTIONS
549
	AST_APP_OPTION_ARG('A', OPT_ANNOUNCE, OPT_ARG_ANNOUNCE),
554
	AST_APP_OPTION_ARG('A', OPT_ANNOUNCE, OPT_ARG_ANNOUNCE),
550
	AST_APP_OPTION('a', OPT_CALLER_ANSWER),
555
	AST_APP_OPTION('a', OPT_CALLER_ANSWER),
551
	AST_APP_OPTION('C', OPT_RESETCDR),
556
	AST_APP_OPTION('C', OPT_RESETCDR),
552
	AST_APP_OPTION('c', OPT_CANCEL_ELSEWHERE),
557
	AST_APP_OPTION('c', OPT_CANCEL_ELSEWHERE),
553
	AST_APP_OPTION('d', OPT_DTMF_EXIT),
558
	AST_APP_OPTION('d', OPT_DTMF_EXIT),
554
	AST_APP_OPTION_ARG('D', OPT_SENDDTMF, OPT_ARG_SENDDTMF),
559
	AST_APP_OPTION_ARG('D', OPT_SENDDTMF, OPT_ARG_SENDDTMF),
555
	AST_APP_OPTION('e', OPT_PEER_H),
560
	AST_APP_OPTION('e', OPT_PEER_H),
556
	AST_APP_OPTION('f', OPT_FORCECLID),
561
	AST_APP_OPTION('f', OPT_FORCECLID),
557
	AST_APP_OPTION_ARG('F', OPT_CALLEE_GO_ON, OPT_ARG_CALLEE_GO_ON),
562
	AST_APP_OPTION_ARG('F', OPT_CALLEE_GO_ON, OPT_ARG_CALLEE_GO_ON),
558
	AST_APP_OPTION('g', OPT_GO_ON),
563
	AST_APP_OPTION('g', OPT_GO_ON),
559
	AST_APP_OPTION_ARG('G', OPT_GOTO, OPT_ARG_GOTO),
564
	AST_APP_OPTION_ARG('G', OPT_GOTO, OPT_ARG_GOTO),
560
	AST_APP_OPTION('h', OPT_CALLEE_HANGUP),
565
	AST_APP_OPTION('h', OPT_CALLEE_HANGUP),
561
	AST_APP_OPTION('H', OPT_CALLER_HANGUP),
566
	AST_APP_OPTION('H', OPT_CALLER_HANGUP),
562
	AST_APP_OPTION('i', OPT_IGNORE_FORWARDING),
567
	AST_APP_OPTION('i', OPT_IGNORE_FORWARDING),
563
	AST_APP_OPTION('I', OPT_IGNORE_CONNECTEDLINE),
568
	AST_APP_OPTION('I', OPT_IGNORE_CONNECTEDLINE),
564
	AST_APP_OPTION('k', OPT_CALLEE_PARK),
569
	AST_APP_OPTION('k', OPT_CALLEE_PARK),
565
	AST_APP_OPTION('K', OPT_CALLER_PARK),
570
	AST_APP_OPTION('K', OPT_CALLER_PARK),
566
	AST_APP_OPTION_ARG('L', OPT_DURATION_LIMIT, OPT_ARG_DURATION_LIMIT),
571
	AST_APP_OPTION_ARG('L', OPT_DURATION_LIMIT, OPT_ARG_DURATION_LIMIT),
567
	AST_APP_OPTION_ARG('m', OPT_MUSICBACK, OPT_ARG_MUSICBACK),
572
	AST_APP_OPTION_ARG('m', OPT_MUSICBACK, OPT_ARG_MUSICBACK),
568
	AST_APP_OPTION_ARG('M', OPT_CALLEE_MACRO, OPT_ARG_CALLEE_MACRO),
573
	AST_APP_OPTION_ARG('M', OPT_CALLEE_MACRO, OPT_ARG_CALLEE_MACRO),
569
	AST_APP_OPTION_ARG('n', OPT_SCREEN_NOINTRO, OPT_ARG_SCREEN_NOINTRO),
574
	AST_APP_OPTION_ARG('n', OPT_SCREEN_NOINTRO, OPT_ARG_SCREEN_NOINTRO),
570
	AST_APP_OPTION('N', OPT_SCREEN_NOCALLERID),
575
	AST_APP_OPTION('N', OPT_SCREEN_NOCALLERID),
571
	AST_APP_OPTION('o', OPT_ORIGINAL_CLID),
576
	AST_APP_OPTION('o', OPT_ORIGINAL_CLID),
572
	AST_APP_OPTION_ARG('O', OPT_OPERMODE, OPT_ARG_OPERMODE),
577
	AST_APP_OPTION_ARG('O', OPT_OPERMODE, OPT_ARG_OPERMODE),
573
	AST_APP_OPTION('p', OPT_SCREENING),
578
	AST_APP_OPTION('p', OPT_SCREENING),
574
	AST_APP_OPTION_ARG('P', OPT_PRIVACY, OPT_ARG_PRIVACY),
579
	AST_APP_OPTION_ARG('P', OPT_PRIVACY, OPT_ARG_PRIVACY),
575
	AST_APP_OPTION('r', OPT_RINGBACK),
580
	AST_APP_OPTION_ARG('r', OPT_RINGBACK, OPT_ARG_RINGBACK),
576
	AST_APP_OPTION_ARG('S', OPT_DURATION_STOP, OPT_ARG_DURATION_STOP),
581
	AST_APP_OPTION_ARG('S', OPT_DURATION_STOP, OPT_ARG_DURATION_STOP),
577
	AST_APP_OPTION('t', OPT_CALLEE_TRANSFER),
582
	AST_APP_OPTION('t', OPT_CALLEE_TRANSFER),
578
	AST_APP_OPTION('T', OPT_CALLER_TRANSFER),
583
	AST_APP_OPTION('T', OPT_CALLER_TRANSFER),
579
	AST_APP_OPTION_ARG('U', OPT_CALLEE_GOSUB, OPT_ARG_CALLEE_GOSUB),
584
	AST_APP_OPTION_ARG('U', OPT_CALLEE_GOSUB, OPT_ARG_CALLEE_GOSUB),
580
	AST_APP_OPTION('w', OPT_CALLEE_MONITOR),
585
	AST_APP_OPTION('w', OPT_CALLEE_MONITOR),
581
	AST_APP_OPTION('W', OPT_CALLER_MONITOR),
586
	AST_APP_OPTION('W', OPT_CALLER_MONITOR),
582
	AST_APP_OPTION('x', OPT_CALLEE_MIXMONITOR),
587
	AST_APP_OPTION('x', OPT_CALLEE_MIXMONITOR),
583
	AST_APP_OPTION('X', OPT_CALLER_MIXMONITOR),
588
	AST_APP_OPTION('X', OPT_CALLER_MIXMONITOR),
584
	AST_APP_OPTION('z', OPT_CANCEL_TIMEOUT),
589
	AST_APP_OPTION('z', OPT_CANCEL_TIMEOUT),
585
END_OPTIONS );
590
END_OPTIONS );
586

    
   
591

   
587
#define CAN_EARLY_BRIDGE(flags,chan,peer) (!ast_test_flag64(flags, OPT_CALLEE_HANGUP | \
592
#define CAN_EARLY_BRIDGE(flags,chan,peer) (!ast_test_flag64(flags, OPT_CALLEE_HANGUP | \
588
	OPT_CALLER_HANGUP | OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER | \
593
	OPT_CALLER_HANGUP | OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER | \
589
	OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR | OPT_CALLEE_PARK |  \
594
	OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR | OPT_CALLEE_PARK |  \
590
	OPT_CALLER_PARK | OPT_ANNOUNCE | OPT_CALLEE_MACRO | OPT_CALLEE_GOSUB) && \
595
	OPT_CALLER_PARK | OPT_ANNOUNCE | OPT_CALLEE_MACRO | OPT_CALLEE_GOSUB) && \
591
	!chan->audiohooks && !peer->audiohooks)
596
	!chan->audiohooks && !peer->audiohooks)
592

    
   
597

   
593
/*
598
/*
594
 * The list of active channels
599
 * The list of active channels
595
 */
600
 */
596
struct chanlist {
601
struct chanlist {
597
	struct chanlist *next;
602
	struct chanlist *next;
598
	struct ast_channel *chan;
603
	struct ast_channel *chan;
599
	uint64_t flags;
604
	uint64_t flags;
600
	struct ast_party_connected_line connected;
605
	struct ast_party_connected_line connected;
601
};
606
};
602

    
   
607

   
603
static int detect_disconnect(struct ast_channel *chan, char code, struct ast_str *featurecode);
608
static int detect_disconnect(struct ast_channel *chan, char code, struct ast_str *featurecode);
604

    
   
609

   
605
static void chanlist_free(struct chanlist *outgoing)
610
static void chanlist_free(struct chanlist *outgoing)
606
{
611
{
607
	ast_party_connected_line_free(&outgoing->connected);
612
	ast_party_connected_line_free(&outgoing->connected);
608
	ast_free(outgoing);
613
	ast_free(outgoing);
609
}
614
}
610

    
   
615

   
611
static void hanguptree(struct chanlist *outgoing, struct ast_channel *exception, int answered_elsewhere)
616
static void hanguptree(struct chanlist *outgoing, struct ast_channel *exception, int answered_elsewhere)
612
{
617
{
613
	/* Hang up a tree of stuff */
618
	/* Hang up a tree of stuff */
614
	struct chanlist *oo;
619
	struct chanlist *oo;
615
	while (outgoing) {
620
	while (outgoing) {
616
		/* Hangup any existing lines we have open */
621
		/* Hangup any existing lines we have open */
617
		if (outgoing->chan && (outgoing->chan != exception)) {
622
		if (outgoing->chan && (outgoing->chan != exception)) {
618
			if (answered_elsewhere) {
623
			if (answered_elsewhere) {
619
				/* The flag is used for local channel inheritance and stuff */
624
				/* The flag is used for local channel inheritance and stuff */
620
				ast_set_flag(outgoing->chan, AST_FLAG_ANSWERED_ELSEWHERE);
625
				ast_set_flag(outgoing->chan, AST_FLAG_ANSWERED_ELSEWHERE);
621
				/* This is for the channel drivers */
626
				/* This is for the channel drivers */
622
				outgoing->chan->hangupcause = AST_CAUSE_ANSWERED_ELSEWHERE;
627
				outgoing->chan->hangupcause = AST_CAUSE_ANSWERED_ELSEWHERE;
623
			}
628
			}
624
			ast_party_connected_line_free(&outgoing->connected);
629
			ast_party_connected_line_free(&outgoing->connected);
625
			ast_hangup(outgoing->chan);
630
			ast_hangup(outgoing->chan);
626
		}
631
		}
627
		oo = outgoing;
632
		oo = outgoing;
628
		outgoing = outgoing->next;
633
		outgoing = outgoing->next;
629
		chanlist_free(oo);
634
		chanlist_free(oo);
630
	}
635
	}
631
}
636
}
632

    
   
637

   
633
#define AST_MAX_WATCHERS 256
638
#define AST_MAX_WATCHERS 256
634

    
   
639

   
635
/*
640
/*
636
 * argument to handle_cause() and other functions.
641
 * argument to handle_cause() and other functions.
637
 */
642
 */
638
struct cause_args {
643
struct cause_args {
639
	struct ast_channel *chan;
644
	struct ast_channel *chan;
640
	int busy;
645
	int busy;
641
	int congestion;
646
	int congestion;
642
	int nochan;
647
	int nochan;
643
};
648
};
644

    
   
649

   
645
static void handle_cause(int cause, struct cause_args *num)
650
static void handle_cause(int cause, struct cause_args *num)
646
{
651
{
647
	struct ast_cdr *cdr = num->chan->cdr;
652
	struct ast_cdr *cdr = num->chan->cdr;
648

    
   
653

   
649
	switch(cause) {
654
	switch(cause) {
650
	case AST_CAUSE_BUSY:
655
	case AST_CAUSE_BUSY:
651
		if (cdr)
656
		if (cdr)
652
			ast_cdr_busy(cdr);
657
			ast_cdr_busy(cdr);
653
		num->busy++;
658
		num->busy++;
654
		break;
659
		break;
655

    
   
660

   
656
	case AST_CAUSE_CONGESTION:
661
	case AST_CAUSE_CONGESTION:
657
		if (cdr)
662
		if (cdr)
658
			ast_cdr_failed(cdr);
663
			ast_cdr_failed(cdr);
659
		num->congestion++;
664
		num->congestion++;
660
		break;
665
		break;
661

    
   
666

   
662
	case AST_CAUSE_NO_ROUTE_DESTINATION:
667
	case AST_CAUSE_NO_ROUTE_DESTINATION:
663
	case AST_CAUSE_UNREGISTERED:
668
	case AST_CAUSE_UNREGISTERED:
664
		if (cdr)
669
		if (cdr)
665
			ast_cdr_failed(cdr);
670
			ast_cdr_failed(cdr);
666
		num->nochan++;
671
		num->nochan++;
667
		break;
672
		break;
668

    
   
673

   
669
	case AST_CAUSE_NO_ANSWER:
674
	case AST_CAUSE_NO_ANSWER:
670
		if (cdr) {
675
		if (cdr) {
671
			ast_cdr_noanswer(cdr);
676
			ast_cdr_noanswer(cdr);
672
		}
677
		}
673
		break;
678
		break;
674
	case AST_CAUSE_NORMAL_CLEARING:
679
	case AST_CAUSE_NORMAL_CLEARING:
675
		break;
680
		break;
676

    
   
681

   
677
	default:
682
	default:
678
		num->nochan++;
683
		num->nochan++;
679
		break;
684
		break;
680
	}
685
	}
681
}
686
}
682

    
   
687

   
683
/* free the buffer if allocated, and set the pointer to the second arg */
688
/* free the buffer if allocated, and set the pointer to the second arg */
684
#define S_REPLACE(s, new_val)		\
689
#define S_REPLACE(s, new_val)		\
685
	do {				\
690
	do {				\
686
		if (s)			\
691
		if (s)			\
687
			ast_free(s);	\
692
			ast_free(s);	\
688
		s = (new_val);		\
693
		s = (new_val);		\
689
	} while (0)
694
	} while (0)
690

    
   
695

   
691
static int onedigit_goto(struct ast_channel *chan, const char *context, char exten, int pri)
696
static int onedigit_goto(struct ast_channel *chan, const char *context, char exten, int pri)
692
{
697
{
693
	char rexten[2] = { exten, '\0' };
698
	char rexten[2] = { exten, '\0' };
694

    
   
699

   
695
	if (context) {
700
	if (context) {
696
		if (!ast_goto_if_exists(chan, context, rexten, pri))
701
		if (!ast_goto_if_exists(chan, context, rexten, pri))
697
			return 1;
702
			return 1;
698
	} else {
703
	} else {
699
		if (!ast_goto_if_exists(chan, chan->context, rexten, pri))
704
		if (!ast_goto_if_exists(chan, chan->context, rexten, pri))
700
			return 1;
705
			return 1;
701
		else if (!ast_strlen_zero(chan->macrocontext)) {
706
		else if (!ast_strlen_zero(chan->macrocontext)) {
702
			if (!ast_goto_if_exists(chan, chan->macrocontext, rexten, pri))
707
			if (!ast_goto_if_exists(chan, chan->macrocontext, rexten, pri))
703
				return 1;
708
				return 1;
704
		}
709
		}
705
	}
710
	}
706
	return 0;
711
	return 0;
707
}
712
}
708

    
   
713

   
709
/* do not call with chan lock held */
714
/* do not call with chan lock held */
710
static const char *get_cid_name(char *name, int namelen, struct ast_channel *chan)
715
static const char *get_cid_name(char *name, int namelen, struct ast_channel *chan)
711
{
716
{
712
	const char *context;
717
	const char *context;
713
	const char *exten;
718
	const char *exten;
714

    
   
719

   
715
	ast_channel_lock(chan);
720
	ast_channel_lock(chan);
716
	context = ast_strdupa(S_OR(chan->macrocontext, chan->context));
721
	context = ast_strdupa(S_OR(chan->macrocontext, chan->context));
717
	exten = ast_strdupa(S_OR(chan->macroexten, chan->exten));
722
	exten = ast_strdupa(S_OR(chan->macroexten, chan->exten));
718
	ast_channel_unlock(chan);
723
	ast_channel_unlock(chan);
719

    
   
724

   
720
	return ast_get_hint(NULL, 0, name, namelen, chan, context, exten) ? name : "";
725
	return ast_get_hint(NULL, 0, name, namelen, chan, context, exten) ? name : "";
721
}
726
}
722

    
   
727

   
723
static void senddialevent(struct ast_channel *src, struct ast_channel *dst, const char *dialstring)
728
static void senddialevent(struct ast_channel *src, struct ast_channel *dst, const char *dialstring)
724
{
729
{
725
	struct ast_channel *chans[] = { src, dst };
730
	struct ast_channel *chans[] = { src, dst };
726
	ast_manager_event_multichan(EVENT_FLAG_CALL, "Dial", 2, chans,
731
	ast_manager_event_multichan(EVENT_FLAG_CALL, "Dial", 2, chans,
727
		"SubEvent: Begin\r\n"
732
		"SubEvent: Begin\r\n"
728
		"Channel: %s\r\n"
733
		"Channel: %s\r\n"
729
		"Destination: %s\r\n"
734
		"Destination: %s\r\n"
730
		"CallerIDNum: %s\r\n"
735
		"CallerIDNum: %s\r\n"
731
		"CallerIDName: %s\r\n"
736
		"CallerIDName: %s\r\n"
732
		"UniqueID: %s\r\n"
737
		"UniqueID: %s\r\n"
733
		"DestUniqueID: %s\r\n"
738
		"DestUniqueID: %s\r\n"
734
		"Dialstring: %s\r\n",
739
		"Dialstring: %s\r\n",
735
		src->name, dst->name, S_OR(src->cid.cid_num, "<unknown>"),
740
		src->name, dst->name, S_OR(src->cid.cid_num, "<unknown>"),
736
		S_OR(src->cid.cid_name, "<unknown>"), src->uniqueid,
741
		S_OR(src->cid.cid_name, "<unknown>"), src->uniqueid,
737
		dst->uniqueid, dialstring ? dialstring : "");
742
		dst->uniqueid, dialstring ? dialstring : "");
738
}
743
}
739

    
   
744

   
740
static void senddialendevent(struct ast_channel *src, const char *dialstatus)
745
static void senddialendevent(struct ast_channel *src, const char *dialstatus)
741
{
746
{
742
	ast_manager_event(src, EVENT_FLAG_CALL, "Dial",
747
	ast_manager_event(src, EVENT_FLAG_CALL, "Dial",
743
		"SubEvent: End\r\n"
748
		"SubEvent: End\r\n"
744
		"Channel: %s\r\n"
749
		"Channel: %s\r\n"
745
		"UniqueID: %s\r\n"
750
		"UniqueID: %s\r\n"
746
		"DialStatus: %s\r\n",
751
		"DialStatus: %s\r\n",
747
		src->name, src->uniqueid, dialstatus);
752
		src->name, src->uniqueid, dialstatus);
748
}
753
}
749

    
   
754

   
750
/*!
755
/*!
751
 * helper function for wait_for_answer()
756
 * helper function for wait_for_answer()
752
 *
757
 *
753
 * XXX this code is highly suspicious, as it essentially overwrites
758
 * XXX this code is highly suspicious, as it essentially overwrites
754
 * the outgoing channel without properly deleting it.
759
 * the outgoing channel without properly deleting it.
755
 *
760
 *
756
 * \todo eventually this function should be intergrated into and replaced by ast_call_forward() 
761
 * \todo eventually this function should be intergrated into and replaced by ast_call_forward() 
757
 */
762
 */
758
static void do_forward(struct chanlist *o,
763
static void do_forward(struct chanlist *o,
759
	struct cause_args *num, struct ast_flags64 *peerflags, int single, int *to)
764
	struct cause_args *num, struct ast_flags64 *peerflags, int single, int *to)
760
{
765
{
761
	char tmpchan[256];
766
	char tmpchan[256];
762
	struct ast_channel *original = o->chan;
767
	struct ast_channel *original = o->chan;
763
	struct ast_channel *c = o->chan; /* the winner */
768
	struct ast_channel *c = o->chan; /* the winner */
764
	struct ast_channel *in = num->chan; /* the input channel */
769
	struct ast_channel *in = num->chan; /* the input channel */
765
	struct ast_party_redirecting *apr = &o->chan->redirecting;
770
	struct ast_party_redirecting *apr = &o->chan->redirecting;
766
	struct ast_party_connected_line *apc = &o->chan->connected;
771
	struct ast_party_connected_line *apc = &o->chan->connected;
767
	char *stuff;
772
	char *stuff;
768
	char *tech;
773
	char *tech;
769
	int cause;
774
	int cause;
770

    
   
775

   
771
	ast_copy_string(tmpchan, c->call_forward, sizeof(tmpchan));
776
	ast_copy_string(tmpchan, c->call_forward, sizeof(tmpchan));
772
	if ((stuff = strchr(tmpchan, '/'))) {
777
	if ((stuff = strchr(tmpchan, '/'))) {
773
		*stuff++ = '\0';
778
		*stuff++ = '\0';
774
		tech = tmpchan;
779
		tech = tmpchan;
775
	} else {
780
	} else {
776
		const char *forward_context;
781
		const char *forward_context;
777
		ast_channel_lock(c);
782
		ast_channel_lock(c);
778
		forward_context = pbx_builtin_getvar_helper(c, "FORWARD_CONTEXT");
783
		forward_context = pbx_builtin_getvar_helper(c, "FORWARD_CONTEXT");
779
		if (ast_strlen_zero(forward_context)) {
784
		if (ast_strlen_zero(forward_context)) {
780
			forward_context = NULL;
785
			forward_context = NULL;
781
		}
786
		}
782
		snprintf(tmpchan, sizeof(tmpchan), "%s@%s", c->call_forward, forward_context ? forward_context : c->context);
787
		snprintf(tmpchan, sizeof(tmpchan), "%s@%s", c->call_forward, forward_context ? forward_context : c->context);
783
		ast_channel_unlock(c);
788
		ast_channel_unlock(c);
784
		stuff = tmpchan;
789
		stuff = tmpchan;
785
		tech = "Local";
790
		tech = "Local";
786
	}
791
	}
787

    
   
792

   
788
	ast_cel_report_event(in, AST_CEL_FORWARD, NULL, c->call_forward, NULL);
793
	ast_cel_report_event(in, AST_CEL_FORWARD, NULL, c->call_forward, NULL);
789

    
   
794

   
790
	/* Before processing channel, go ahead and check for forwarding */
795
	/* Before processing channel, go ahead and check for forwarding */
791
	ast_verb(3, "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, c->name);
796
	ast_verb(3, "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, c->name);
792
	/* If we have been told to ignore forwards, just set this channel to null and continue processing extensions normally */
797
	/* If we have been told to ignore forwards, just set this channel to null and continue processing extensions normally */
793
	if (ast_test_flag64(peerflags, OPT_IGNORE_FORWARDING)) {
798
	if (ast_test_flag64(peerflags, OPT_IGNORE_FORWARDING)) {
794
		ast_verb(3, "Forwarding %s to '%s/%s' prevented.\n", in->name, tech, stuff);
799
		ast_verb(3, "Forwarding %s to '%s/%s' prevented.\n", in->name, tech, stuff);
795
		c = o->chan = NULL;
800
		c = o->chan = NULL;
796
		cause = AST_CAUSE_BUSY;
801
		cause = AST_CAUSE_BUSY;
797
	} else {
802
	} else {
798
		/* Setup parameters */
803
		/* Setup parameters */
799
		c = o->chan = ast_request(tech, in->nativeformats, in, stuff, &cause);
804
		c = o->chan = ast_request(tech, in->nativeformats, in, stuff, &cause);
800
		if (c) {
805
		if (c) {
801
			if (single)
806
			if (single)
802
				ast_channel_make_compatible(o->chan, in);
807
				ast_channel_make_compatible(o->chan, in);
803
			ast_channel_inherit_variables(in, o->chan);
808
			ast_channel_inherit_variables(in, o->chan);
804
			ast_channel_datastore_inherit(in, o->chan);
809
			ast_channel_datastore_inherit(in, o->chan);
805
		} else
810
		} else
806
			ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause);
811
			ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s' (cause = %d)\n", tech, stuff, cause);
807
	}
812
	}
808
	if (!c) {
813
	if (!c) {
809
		ast_clear_flag64(o, DIAL_STILLGOING);
814
		ast_clear_flag64(o, DIAL_STILLGOING);
810
		handle_cause(cause, num);
815
		handle_cause(cause, num);
811
		ast_hangup(original);
816
		ast_hangup(original);
812
	} else {
817
	} else {
813
		if (single && CAN_EARLY_BRIDGE(peerflags, c, in)) {
818
		if (single && CAN_EARLY_BRIDGE(peerflags, c, in)) {
814
			ast_rtp_instance_early_bridge_make_compatible(c, in);
819
			ast_rtp_instance_early_bridge_make_compatible(c, in);
815
		}
820
		}
816

    
   
821

   
817
		c->cdrflags = in->cdrflags;
822
		c->cdrflags = in->cdrflags;
818

    
   
823

   
819
		ast_channel_set_redirecting(c, apr);
824
		ast_channel_set_redirecting(c, apr);
820
		ast_channel_lock(c);
825
		ast_channel_lock(c);
821
		while (ast_channel_trylock(in)) {
826
		while (ast_channel_trylock(in)) {
822
			CHANNEL_DEADLOCK_AVOIDANCE(c);
827
			CHANNEL_DEADLOCK_AVOIDANCE(c);
823
		}
828
		}
824
		S_REPLACE(c->cid.cid_rdnis, ast_strdup(S_OR(original->cid.cid_rdnis, S_OR(in->macroexten, in->exten))));
829
		S_REPLACE(c->cid.cid_rdnis, ast_strdup(S_OR(original->cid.cid_rdnis, S_OR(in->macroexten, in->exten))));
825

    
   
830

   
826
		c->cid.cid_tns = in->cid.cid_tns;
831
		c->cid.cid_tns = in->cid.cid_tns;
827

    
   
832

   
828
		if (ast_test_flag64(o, OPT_FORCECLID)) {
833
		if (ast_test_flag64(o, OPT_FORCECLID)) {
829
			S_REPLACE(c->cid.cid_num, ast_strdupa(S_OR(in->macroexten, in->exten)));
834
			S_REPLACE(c->cid.cid_num, ast_strdupa(S_OR(in->macroexten, in->exten)));
830
			S_REPLACE(c->cid.cid_name, NULL);
835
			S_REPLACE(c->cid.cid_name, NULL);
831
			ast_string_field_set(c, accountcode, c->accountcode);
836
			ast_string_field_set(c, accountcode, c->accountcode);
832
		} else {
837
		} else {
833
			ast_party_caller_copy(&c->cid, &in->cid);
838
			ast_party_caller_copy(&c->cid, &in->cid);
834
			ast_string_field_set(c, accountcode, in->accountcode);
839
			ast_string_field_set(c, accountcode, in->accountcode);
835
		}
840
		}
836
		ast_party_connected_line_copy(&c->connected, apc);
841
		ast_party_connected_line_copy(&c->connected, apc);
837

    
   
842

   
838
		S_REPLACE(in->cid.cid_rdnis, ast_strdup(c->cid.cid_rdnis));
843
		S_REPLACE(in->cid.cid_rdnis, ast_strdup(c->cid.cid_rdnis));
839
		ast_channel_update_redirecting(in, apr);
844
		ast_channel_update_redirecting(in, apr);
840

    
   
845

   
841
		ast_clear_flag64(peerflags, OPT_IGNORE_CONNECTEDLINE);
846
		ast_clear_flag64(peerflags, OPT_IGNORE_CONNECTEDLINE);
842
		if (ast_test_flag64(peerflags, OPT_CANCEL_TIMEOUT)) {
847
		if (ast_test_flag64(peerflags, OPT_CANCEL_TIMEOUT)) {
843
			*to = -1;
848
			*to = -1;
844
		}
849
		}
845

    
   
850

   
846
		ast_channel_unlock(in);
851
		ast_channel_unlock(in);
847
		ast_channel_unlock(c);
852
		ast_channel_unlock(c);
848

    
   
853

   
849
		if (ast_call(c, tmpchan, 0)) {
854
		if (ast_call(c, tmpchan, 0)) {
850
			ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
855
			ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
851
			ast_clear_flag64(o, DIAL_STILLGOING);
856
			ast_clear_flag64(o, DIAL_STILLGOING);
852
			ast_hangup(original);
857
			ast_hangup(original);
853
			ast_hangup(c);
858
			ast_hangup(c);
854
			c = o->chan = NULL;
859
			c = o->chan = NULL;
855
			num->nochan++;
860
			num->nochan++;
856
		} else {
861
		} else {
857
			ast_channel_lock(c);
862
			ast_channel_lock(c);
858
			while (ast_channel_trylock(in)) {
863
			while (ast_channel_trylock(in)) {
859
				CHANNEL_DEADLOCK_AVOIDANCE(c);
864
				CHANNEL_DEADLOCK_AVOIDANCE(c);
860
			}
865
			}
861
			senddialevent(in, c, stuff);
866
			senddialevent(in, c, stuff);
862
			if (!ast_test_flag64(peerflags, OPT_ORIGINAL_CLID)) {
867
			if (!ast_test_flag64(peerflags, OPT_ORIGINAL_CLID)) {
863
				char cidname[AST_MAX_EXTENSION] = "";
868
				char cidname[AST_MAX_EXTENSION] = "";
864
				const char *tmpexten;
869
				const char *tmpexten;
865
				tmpexten = ast_strdupa(S_OR(in->macroexten, in->exten));
870
				tmpexten = ast_strdupa(S_OR(in->macroexten, in->exten));
866
				ast_channel_unlock(in);
871
				ast_channel_unlock(in);
867
				ast_channel_unlock(c);
872
				ast_channel_unlock(c);
868
				ast_set_callerid(c, tmpexten, get_cid_name(cidname, sizeof(cidname), in), NULL);
873
				ast_set_callerid(c, tmpexten, get_cid_name(cidname, sizeof(cidname), in), NULL);
869
			} else {
874
			} else {
870
				ast_channel_unlock(in);
875
				ast_channel_unlock(in);
871
				ast_channel_unlock(c);
876
				ast_channel_unlock(c);
872
			}
877
			}
873
			/* Hangup the original channel now, in case we needed it */
878
			/* Hangup the original channel now, in case we needed it */
874
			ast_hangup(original);
879
			ast_hangup(original);
875
		}
880
		}
876
		if (single) {
881
		if (single) {
877
			ast_indicate(in, -1);
882
			ast_indicate(in, -1);
878
		}
883
		}
879
	}
884
	}
880
}
885
}
881

    
   
886

   
882
/* argument used for some functions. */
887
/* argument used for some functions. */
883
struct privacy_args {
888
struct privacy_args {
884
	int sentringing;
889
	int sentringing;
885
	int privdb_val;
890
	int privdb_val;
886
	char privcid[256];
891
	char privcid[256];
887
	char privintro[1024];
892
	char privintro[1024];
888
	char status[256];
893
	char status[256];
889
};
894
};
890

    
   
895

   
891
static struct ast_channel *wait_for_answer(struct ast_channel *in,
896
static struct ast_channel *wait_for_answer(struct ast_channel *in,
892
	struct chanlist *outgoing, int *to, struct ast_flags64 *peerflags,
897
	struct chanlist *outgoing, int *to, struct ast_flags64 *peerflags,

    
   
898
	char *opt_args[],
893
	struct privacy_args *pa,
899
	struct privacy_args *pa,
894
	const struct cause_args *num_in, int *result, char *dtmf_progress)
900
	const struct cause_args *num_in, int *result, char *dtmf_progress)
895
{
901
{
896
	struct cause_args num = *num_in;
902
	struct cause_args num = *num_in;
897
	int prestart = num.busy + num.congestion + num.nochan;
903
	int prestart = num.busy + num.congestion + num.nochan;
898
	int orig = *to;
904
	int orig = *to;
899
	struct ast_channel *peer = NULL;
905
	struct ast_channel *peer = NULL;
900
	/* single is set if only one destination is enabled */
906
	/* single is set if only one destination is enabled */
901
	int single = outgoing && !outgoing->next;
907
	int single = outgoing && !outgoing->next;
902
#ifdef HAVE_EPOLL
908
#ifdef HAVE_EPOLL
903
	struct chanlist *epollo;
909
	struct chanlist *epollo;
904
#endif
910
#endif
905
	struct ast_party_connected_line connected_caller;
911
	struct ast_party_connected_line connected_caller;
906
	struct ast_str *featurecode = ast_str_alloca(FEATURE_MAX_LEN + 1);
912
	struct ast_str *featurecode = ast_str_alloca(FEATURE_MAX_LEN + 1);
907

    
   
913

   
908
	ast_party_connected_line_init(&connected_caller);
914
	ast_party_connected_line_init(&connected_caller);
909
	if (single) {
915
	if (single) {
910
		/* Turn off hold music, etc */
916
		/* Turn off hold music, etc */
911
		if (!ast_test_flag64(outgoing, OPT_MUSICBACK | OPT_RINGBACK))
917
		if (!ast_test_flag64(outgoing, OPT_MUSICBACK | OPT_RINGBACK)) {
912
			ast_deactivate_generator(in);
918
			ast_deactivate_generator(in);
913

    
   
919
			/* If we are calling a single channel, and not providing ringback or music, */
914
		/* If we are calling a single channel, make them compatible for in-band tone purpose */
920
			/* then, make them compatible for in-band tone purpose */
915
		ast_channel_make_compatible(outgoing->chan, in);
921
			ast_channel_make_compatible(outgoing->chan, in);

    
   
922
		}
916

    
   
923

   
917
		if (!ast_test_flag64(peerflags, OPT_IGNORE_CONNECTEDLINE) && !ast_test_flag64(outgoing, DIAL_NOCONNECTEDLINE)) {
924
		if (!ast_test_flag64(peerflags, OPT_IGNORE_CONNECTEDLINE) && !ast_test_flag64(outgoing, DIAL_NOCONNECTEDLINE)) {
918
			ast_channel_lock(outgoing->chan);
925
			ast_channel_lock(outgoing->chan);
919
			ast_connected_line_copy_from_caller(&connected_caller, &outgoing->chan->cid);
926
			ast_connected_line_copy_from_caller(&connected_caller, &outgoing->chan->cid);
920
			ast_channel_unlock(outgoing->chan);
927
			ast_channel_unlock(outgoing->chan);
921
			connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
928
			connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
922
			ast_channel_update_connected_line(in, &connected_caller);
929
			ast_channel_update_connected_line(in, &connected_caller);
923
			ast_party_connected_line_free(&connected_caller);
930
			ast_party_connected_line_free(&connected_caller);
924
		}
931
		}
925
	}
932
	}
926

    
   
933

   
927
#ifdef HAVE_EPOLL
934
#ifdef HAVE_EPOLL
928
	for (epollo = outgoing; epollo; epollo = epollo->next)
935
	for (epollo = outgoing; epollo; epollo = epollo->next)
929
		ast_poll_channel_add(in, epollo->chan);
936
		ast_poll_channel_add(in, epollo->chan);
930
#endif
937
#endif
931

    
   
938

   
932
	while (*to && !peer) {
939
	while (*to && !peer) {
933
		struct chanlist *o;
940
		struct chanlist *o;
934
		int pos = 0; /* how many channels do we handle */
941
		int pos = 0; /* how many channels do we handle */
935
		int numlines = prestart;
942
		int numlines = prestart;
936
		struct ast_channel *winner;
943
		struct ast_channel *winner;
937
		struct ast_channel *watchers[AST_MAX_WATCHERS];
944
		struct ast_channel *watchers[AST_MAX_WATCHERS];
938

    
   
945

   
939
		watchers[pos++] = in;
946
		watchers[pos++] = in;
940
		for (o = outgoing; o; o = o->next) {
947
		for (o = outgoing; o; o = o->next) {
941
			/* Keep track of important channels */
948
			/* Keep track of important channels */
942
			if (ast_test_flag64(o, DIAL_STILLGOING) && o->chan)
949
			if (ast_test_flag64(o, DIAL_STILLGOING) && o->chan)
943
				watchers[pos++] = o->chan;
950
				watchers[pos++] = o->chan;
944
			numlines++;
951
			numlines++;
945
		}
952
		}
946
		if (pos == 1) { /* only the input channel is available */
953
		if (pos == 1) { /* only the input channel is available */
947
			if (numlines == (num.busy + num.congestion + num.nochan)) {
954
			if (numlines == (num.busy + num.congestion + num.nochan)) {
948
				ast_verb(2, "Everyone is busy/congested at this time (%d:%d/%d/%d)\n", numlines, num.busy, num.congestion, num.nochan);
955
				ast_verb(2, "Everyone is busy/congested at this time (%d:%d/%d/%d)\n", numlines, num.busy, num.congestion, num.nochan);
949
				if (num.busy)
956
				if (num.busy)
950
					strcpy(pa->status, "BUSY");
957
					strcpy(pa->status, "BUSY");
951
				else if (num.congestion)
958
				else if (num.congestion)
952
					strcpy(pa->status, "CONGESTION");
959
					strcpy(pa->status, "CONGESTION");
953
				else if (num.nochan)
960
				else if (num.nochan)
954
					strcpy(pa->status, "CHANUNAVAIL");
961
					strcpy(pa->status, "CHANUNAVAIL");
955
			} else {
962
			} else {
956
				ast_verb(3, "No one is available to answer at this time (%d:%d/%d/%d)\n", numlines, num.busy, num.congestion, num.nochan);
963
				ast_verb(3, "No one is available to answer at this time (%d:%d/%d/%d)\n", numlines, num.busy, num.congestion, num.nochan);
957
			}
964
			}
958
			*to = 0;
965
			*to = 0;
959
			return NULL;
966
			return NULL;
960
		}
967
		}
961
		winner = ast_waitfor_n(watchers, pos, to);
968
		winner = ast_waitfor_n(watchers, pos, to);
962
		for (o = outgoing; o; o = o->next) {
969
		for (o = outgoing; o; o = o->next) {
963
			struct ast_frame *f;
970
			struct ast_frame *f;
964
			struct ast_channel *c = o->chan;
971
			struct ast_channel *c = o->chan;
965

    
   
972

   
966
			if (c == NULL)
973
			if (c == NULL)
967
				continue;
974
				continue;
968
			if (ast_test_flag64(o, DIAL_STILLGOING) && c->_state == AST_STATE_UP) {
975
			if (ast_test_flag64(o, DIAL_STILLGOING) && c->_state == AST_STATE_UP) {
969
				if (!peer) {
976
				if (!peer) {
970
					ast_verb(3, "%s answered %s\n", c->name, in->name);
977
					ast_verb(3, "%s answered %s\n", c->name, in->name);
971
					if (!single && !ast_test_flag64(peerflags, OPT_IGNORE_CONNECTEDLINE)) {
978
					if (!single && !ast_test_flag64(peerflags, OPT_IGNORE_CONNECTEDLINE)) {
972
						if (o->connected.id.number) {
979
						if (o->connected.id.number) {
973
							if (ast_channel_connected_line_macro(c, in, &o->connected, 1, 0)) {
980
							if (ast_channel_connected_line_macro(c, in, &o->connected, 1, 0)) {
974
								ast_channel_update_connected_line(in, &o->connected);
981
								ast_channel_update_connected_line(in, &o->connected);
975
							}
982
							}
976
						} else if (!ast_test_flag64(o, DIAL_NOCONNECTEDLINE)) {
983
						} else if (!ast_test_flag64(o, DIAL_NOCONNECTEDLINE)) {
977
							ast_channel_lock(c);
984
							ast_channel_lock(c);
978
							ast_connected_line_copy_from_caller(&connected_caller, &c->cid);
985
							ast_connected_line_copy_from_caller(&connected_caller, &c->cid);
979
							ast_channel_unlock(c);
986
							ast_channel_unlock(c);
980
							connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
987
							connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
981
							ast_channel_update_connected_line(in, &connected_caller);
988
							ast_channel_update_connected_line(in, &connected_caller);
982
							ast_party_connected_line_free(&connected_caller);
989
							ast_party_connected_line_free(&connected_caller);
983
						}
990
						}
984
					}
991
					}
985
					peer = c;
992
					peer = c;
986
					ast_copy_flags64(peerflags, o,
993
					ast_copy_flags64(peerflags, o,
987
						OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
994
						OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
988
						OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
995
						OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
989
						OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
996
						OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
990
						OPT_CALLEE_PARK | OPT_CALLER_PARK |
997
						OPT_CALLEE_PARK | OPT_CALLER_PARK |
991
						OPT_CALLEE_MIXMONITOR | OPT_CALLER_MIXMONITOR |
998
						OPT_CALLEE_MIXMONITOR | OPT_CALLER_MIXMONITOR |
992
						DIAL_NOFORWARDHTML);
999
						DIAL_NOFORWARDHTML);
993
					ast_string_field_set(c, dialcontext, "");
1000
					ast_string_field_set(c, dialcontext, "");
994
					ast_copy_string(c->exten, "", sizeof(c->exten));
1001
					ast_copy_string(c->exten, "", sizeof(c->exten));
995
				}
1002
				}
996
				continue;
1003
				continue;
997
			}
1004
			}
998
			if (c != winner)
1005
			if (c != winner)
999
				continue;
1006
				continue;
1000
			/* here, o->chan == c == winner */
1007
			/* here, o->chan == c == winner */
1001
			if (!ast_strlen_zero(c->call_forward)) {
1008
			if (!ast_strlen_zero(c->call_forward)) {
1002
				pa->sentringing = 0;
1009
				pa->sentringing = 0;
1003
				do_forward(o, &num, peerflags, single, to);
1010
				do_forward(o, &num, peerflags, single, to);
1004
				continue;
1011
				continue;
1005
			}
1012
			}
1006
			f = ast_read(winner);
1013
			f = ast_read(winner);
1007
			if (!f) {
1014
			if (!f) {
1008
				in->hangupcause = c->hangupcause;
1015
				in->hangupcause = c->hangupcause;
1009
#ifdef HAVE_EPOLL
1016
#ifdef HAVE_EPOLL
1010
				ast_poll_channel_del(in, c);
1017
				ast_poll_channel_del(in, c);
1011
#endif
1018
#endif
1012
				ast_hangup(c);
1019
				ast_hangup(c);
1013
				c = o->chan = NULL;
1020
				c = o->chan = NULL;
1014
				ast_clear_flag64(o, DIAL_STILLGOING);
1021
				ast_clear_flag64(o, DIAL_STILLGOING);
1015
				handle_cause(in->hangupcause, &num);
1022
				handle_cause(in->hangupcause, &num);
1016
				continue;
1023
				continue;
1017
			}
1024
			}
1018
			if (f->frametype == AST_FRAME_CONTROL) {
1025
			if (f->frametype == AST_FRAME_CONTROL) {
1019
				switch (f->subclass.integer) {
1026
				switch (f->subclass.integer) {
1020
				case AST_CONTROL_ANSWER:
1027
				case AST_CONTROL_ANSWER:
1021
					/* This is our guy if someone answered. */
1028
					/* This is our guy if someone answered. */
1022
					if (!peer) {
1029
					if (!peer) {
1023
						ast_verb(3, "%s answered %s\n", c->name, in->name);
1030
						ast_verb(3, "%s answered %s\n", c->name, in->name);
1024
						if (!single && !ast_test_flag64(peerflags, OPT_IGNORE_CONNECTEDLINE)) {
1031
						if (!single && !ast_test_flag64(peerflags, OPT_IGNORE_CONNECTEDLINE)) {
1025
							if (o->connected.id.number) {
1032
							if (o->connected.id.number) {
1026
								if (ast_channel_connected_line_macro(c, in, &o->connected, 1, 0)) {
1033
								if (ast_channel_connected_line_macro(c, in, &o->connected, 1, 0)) {
1027
									ast_channel_update_connected_line(in, &o->connected);
1034
									ast_channel_update_connected_line(in, &o->connected);
1028
								}
1035
								}
1029
							} else if (!ast_test_flag64(o, DIAL_NOCONNECTEDLINE)) {
1036
							} else if (!ast_test_flag64(o, DIAL_NOCONNECTEDLINE)) {
1030
								ast_channel_lock(c);
1037
								ast_channel_lock(c);
1031
								ast_connected_line_copy_from_caller(&connected_caller, &c->cid);
1038
								ast_connected_line_copy_from_caller(&connected_caller, &c->cid);
1032
								ast_channel_unlock(c);
1039
								ast_channel_unlock(c);
1033
								connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
1040
								connected_caller.source = AST_CONNECTED_LINE_UPDATE_SOURCE_ANSWER;
1034
								ast_channel_update_connected_line(in, &connected_caller);
1041
								ast_channel_update_connected_line(in, &connected_caller);
1035
								ast_party_connected_line_free(&connected_caller);
1042
								ast_party_connected_line_free(&connected_caller);
1036
							}
1043
							}
1037
						}
1044
						}
1038
						peer = c;
1045
						peer = c;
1039
						if (peer->cdr) {
1046
						if (peer->cdr) {
1040
							peer->cdr->answer = ast_tvnow();
1047
							peer->cdr->answer = ast_tvnow();
1041
							peer->cdr->disposition = AST_CDR_ANSWERED;
1048
							peer->cdr->disposition = AST_CDR_ANSWERED;
1042
						}
1049
						}
1043
						ast_copy_flags64(peerflags, o,
1050
						ast_copy_flags64(peerflags, o,
1044
							OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
1051
							OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
1045
							OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
1052
							OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
1046
							OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
1053
							OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
1047
							OPT_CALLEE_PARK | OPT_CALLER_PARK |
1054
							OPT_CALLEE_PARK | OPT_CALLER_PARK |
1048
							OPT_CALLEE_MIXMONITOR | OPT_CALLER_MIXMONITOR |
1055
							OPT_CALLEE_MIXMONITOR | OPT_CALLER_MIXMONITOR |
1049
							DIAL_NOFORWARDHTML);
1056
							DIAL_NOFORWARDHTML);
1050
						ast_string_field_set(c, dialcontext, "");
1057
						ast_string_field_set(c, dialcontext, "");
1051
						ast_copy_string(c->exten, "", sizeof(c->exten));
1058
						ast_copy_string(c->exten, "", sizeof(c->exten));
1052
						if (CAN_EARLY_BRIDGE(peerflags, in, peer))
1059
						if (CAN_EARLY_BRIDGE(peerflags, in, peer))
1053
							/* Setup early bridge if appropriate */
1060
							/* Setup early bridge if appropriate */
1054
							ast_channel_early_bridge(in, peer);
1061
							ast_channel_early_bridge(in, peer);
1055
					}
1062
					}
1056
					/* If call has been answered, then the eventual hangup is likely to be normal hangup */
1063
					/* If call has been answered, then the eventual hangup is likely to be normal hangup */
1057
					in->hangupcause = AST_CAUSE_NORMAL_CLEARING;
1064
					in->hangupcause = AST_CAUSE_NORMAL_CLEARING;
1058
					c->hangupcause = AST_CAUSE_NORMAL_CLEARING;
1065
					c->hangupcause = AST_CAUSE_NORMAL_CLEARING;
1059
					break;
1066
					break;
1060
				case AST_CONTROL_BUSY:
1067
				case AST_CONTROL_BUSY:
1061
					ast_verb(3, "%s is busy\n", c->name);
1068
					ast_verb(3, "%s is busy\n", c->name);
1062
					in->hangupcause = c->hangupcause;
1069
					in->hangupcause = c->hangupcause;
1063
					ast_hangup(c);
1070
					ast_hangup(c);
1064
					c = o->chan = NULL;
1071
					c = o->chan = NULL;
1065
					ast_clear_flag64(o, DIAL_STILLGOING);
1072
					ast_clear_flag64(o, DIAL_STILLGOING);
1066
					handle_cause(AST_CAUSE_BUSY, &num);
1073
					handle_cause(AST_CAUSE_BUSY, &num);
1067
					break;
1074
					break;
1068
				case AST_CONTROL_CONGESTION:
1075
				case AST_CONTROL_CONGESTION:
1069
					ast_verb(3, "%s is circuit-busy\n", c->name);
1076
					ast_verb(3, "%s is circuit-busy\n", c->name);
1070
					in->hangupcause = c->hangupcause;
1077
					in->hangupcause = c->hangupcause;
1071
					ast_hangup(c);
1078
					ast_hangup(c);
1072
					c = o->chan = NULL;
1079
					c = o->chan = NULL;
1073
					ast_clear_flag64(o, DIAL_STILLGOING);
1080
					ast_clear_flag64(o, DIAL_STILLGOING);
1074
					handle_cause(AST_CAUSE_CONGESTION, &num);
1081
					handle_cause(AST_CAUSE_CONGESTION, &num);
1075
					break;
1082
					break;
1076
				case AST_CONTROL_RINGING:
1083
				case AST_CONTROL_RINGING:
1077
					ast_verb(3, "%s is ringing\n", c->name);
1084
					ast_verb(3, "%s is ringing\n", c->name);
1078
					/* Setup early media if appropriate */
1085
					/* Setup early media if appropriate */
1079
					if (single && CAN_EARLY_BRIDGE(peerflags, in, c))
1086
					if (single && CAN_EARLY_BRIDGE(peerflags, in, c))
1080
						ast_channel_early_bridge(in, c);
1087
						ast_channel_early_bridge(in, c);
1081
					if (!(pa->sentringing) && !ast_test_flag64(outgoing, OPT_MUSICBACK)) {
1088
					if (!(pa->sentringing) && !ast_test_flag64(outgoing, OPT_MUSICBACK) && ast_strlen_zero(opt_args[OPT_ARG_RINGBACK])) {
1082
						ast_indicate(in, AST_CONTROL_RINGING);
1089
						ast_indicate(in, AST_CONTROL_RINGING);
1083
						pa->sentringing++;
1090
						pa->sentringing++;
1084
					}
1091
					}
1085
					break;
1092
					break;
1086
				case AST_CONTROL_PROGRESS:
1093
				case AST_CONTROL_PROGRESS:
1087
					ast_verb(3, "%s is making progress passing it to %s\n", c->name, in->name);
1094
					ast_verb(3, "%s is making progress passing it to %s\n", c->name, in->name);
1088
					/* Setup early media if appropriate */
1095
					/* Setup early media if appropriate */
1089
					if (single && CAN_EARLY_BRIDGE(peerflags, in, c))
1096
					if (single && CAN_EARLY_BRIDGE(peerflags, in, c))
1090
						ast_channel_early_bridge(in, c);
1097
						ast_channel_early_bridge(in, c);
1091
					if (!ast_test_flag64(outgoing, OPT_RINGBACK))
1098
					if (!ast_test_flag64(outgoing, OPT_RINGBACK))
1092
						if (single || (!single && !pa->sentringing)) {
1099
						if (single || (!single && !pa->sentringing)) {
1093
							ast_indicate(in, AST_CONTROL_PROGRESS);
1100
							ast_indicate(in, AST_CONTROL_PROGRESS);
1094
						}
1101
						}
1095
						if(!ast_strlen_zero(dtmf_progress)) {
1102
						if(!ast_strlen_zero(dtmf_progress)) {
1096
							ast_verb(3, "Sending DTMF '%s' to the called party as result of receiving a PROGRESS message.\n", dtmf_progress);
1103
							ast_verb(3, "Sending DTMF '%s' to the called party as result of receiving a PROGRESS message.\n", dtmf_progress);
1097
							ast_dtmf_stream(c, in, dtmf_progress, 250, 0);
1104
							ast_dtmf_stream(c, in, dtmf_progress, 250, 0);
1098
						}
1105
						}
1099
					break;
1106
					break;
1100
				case AST_CONTROL_VIDUPDATE:
1107
				case AST_CONTROL_VIDUPDATE:
1101
					ast_verb(3, "%s requested a video update, passing it to %s\n", c->name, in->name);
1108
					ast_verb(3, "%s requested a video update, passing it to %s\n", c->name, in->name);
1102
					ast_indicate(in, AST_CONTROL_VIDUPDATE);
1109
					ast_indicate(in, AST_CONTROL_VIDUPDATE);
1103
					break;
1110
					break;
1104
				case AST_CONTROL_SRCUPDATE:
1111
				case AST_CONTROL_SRCUPDATE:
1105
					ast_verb(3, "%s requested a source update, passing it to %s\n", c->name, in->name);
1112
					ast_verb(3, "%s requested a source update, passing it to %s\n", c->name, in->name);
1106
					ast_indicate(in, AST_CONTROL_SRCUPDATE);
1113
					ast_indicate(in, AST_CONTROL_SRCUPDATE);
1107
					break;
1114
					break;
1108
				case AST_CONTROL_CONNECTED_LINE:
1115
				case AST_CONTROL_CONNECTED_LINE:
1109
					if (ast_test_flag64(peerflags, OPT_IGNORE_CONNECTEDLINE)) {
1116
					if (ast_test_flag64(peerflags, OPT_IGNORE_CONNECTEDLINE)) {
1110
						ast_verb(3, "Connected line update to %s prevented.\n", in->name);
1117
						ast_verb(3, "Connected line update to %s prevented.\n", in->name);
1111
					} else if (!single) {
1118
					} else if (!single) {
1112
						struct ast_party_connected_line connected;
1119
						struct ast_party_connected_line connected;
1113
						ast_verb(3, "%s connected line has changed. Saving it until answer for %s\n", c->name, in->name);
1120
						ast_verb(3, "%s connected line has changed. Saving it until answer for %s\n", c->name, in->name);
1114
						ast_party_connected_line_set_init(&connected, &o->connected);
1121
						ast_party_connected_line_set_init(&connected, &o->connected);
1115
						ast_connected_line_parse_data(f->data.ptr, f->datalen, &connected);
1122
						ast_connected_line_parse_data(f->data.ptr, f->datalen, &connected);
1116
						ast_party_connected_line_set(&o->connected, &connected);
1123
						ast_party_connected_line_set(&o->connected, &connected);
1117
						ast_party_connected_line_free(&connected);
1124
						ast_party_connected_line_free(&connected);
1118
					} else {
1125
					} else {
1119
						if (ast_channel_connected_line_macro(c, in, f, 1, 1)) {
1126
						if (ast_channel_connected_line_macro(c, in, f, 1, 1)) {
1120
							ast_indicate_data(in, AST_CONTROL_CONNECTED_LINE, f->data.ptr, f->datalen);
1127
							ast_indicate_data(in, AST_CONTROL_CONNECTED_LINE, f->data.ptr, f->datalen);
1121
						}
1128
						}
1122
					}
1129
					}
1123
					break;
1130
					break;
1124
				case AST_CONTROL_REDIRECTING:
1131
				case AST_CONTROL_REDIRECTING:
1125
					if (ast_test_flag64(peerflags, OPT_IGNORE_CONNECTEDLINE)) {
1132
					if (ast_test_flag64(peerflags, OPT_IGNORE_CONNECTEDLINE)) {
1126
						ast_verb(3, "Redirecting update to %s prevented.\n", in->name);
1133
						ast_verb(3, "Redirecting update to %s prevented.\n", in->name);
1127
					} else {
1134
					} else {
1128
						ast_verb(3, "%s redirecting info has changed, passing it to %s\n", c->name, in->name);
1135
						ast_verb(3, "%s redirecting info has changed, passing it to %s\n", c->name, in->name);
1129
						ast_indicate_data(in, AST_CONTROL_REDIRECTING, f->data.ptr, f->datalen);
1136
						ast_indicate_data(in, AST_CONTROL_REDIRECTING, f->data.ptr, f->datalen);
1130
						pa->sentringing = 0;
1137
						pa->sentringing = 0;
1131
					}
1138
					}
1132
					break;
1139
					break;
1133
				case AST_CONTROL_PROCEEDING:
1140
				case AST_CONTROL_PROCEEDING:
1134
					ast_verb(3, "%s is proceeding passing it to %s\n", c->name, in->name);
1141
					ast_verb(3, "%s is proceeding passing it to %s\n", c->name, in->name);
1135
					if (single && CAN_EARLY_BRIDGE(peerflags, in, c))
1142
					if (single && CAN_EARLY_BRIDGE(peerflags, in, c))
1136
						ast_channel_early_bridge(in, c);
1143
						ast_channel_early_bridge(in, c);
1137
					if (!ast_test_flag64(outgoing, OPT_RINGBACK))
1144
					if (!ast_test_flag64(outgoing, OPT_RINGBACK))
1138
						ast_indicate(in, AST_CONTROL_PROCEEDING);
1145
						ast_indicate(in, AST_CONTROL_PROCEEDING);
1139
					break;
1146
					break;
1140
				case AST_CONTROL_HOLD:
1147
				case AST_CONTROL_HOLD:
1141
					ast_verb(3, "Call on %s placed on hold\n", c->name);
1148
					ast_verb(3, "Call on %s placed on hold\n", c->name);
1142
					ast_indicate(in, AST_CONTROL_HOLD);
1149
					ast_indicate(in, AST_CONTROL_HOLD);
1143
					break;
1150
					break;
1144
				case AST_CONTROL_UNHOLD:
1151
				case AST_CONTROL_UNHOLD:
1145
					ast_verb(3, "Call on %s left from hold\n", c->name);
1152
					ast_verb(3, "Call on %s left from hold\n", c->name);
1146
					ast_indicate(in, AST_CONTROL_UNHOLD);
1153
					ast_indicate(in, AST_CONTROL_UNHOLD);
1147
					break;
1154
					break;
1148
				case AST_CONTROL_OFFHOOK:
1155
				case AST_CONTROL_OFFHOOK:
1149
				case AST_CONTROL_FLASH:
1156
				case AST_CONTROL_FLASH:
1150
					/* Ignore going off hook and flash */
1157
					/* Ignore going off hook and flash */
1151
					break;
1158
					break;
1152
				case -1:
1159
				case -1:
1153
					if (!ast_test_flag64(outgoing, OPT_RINGBACK | OPT_MUSICBACK)) {
1160
					if (!ast_test_flag64(outgoing, OPT_RINGBACK | OPT_MUSICBACK)) {
1154
						ast_verb(3, "%s stopped sounds\n", c->name);
1161
						ast_verb(3, "%s stopped sounds\n", c->name);
1155
						ast_indicate(in, -1);
1162
						ast_indicate(in, -1);
1156
						pa->sentringing = 0;
1163
						pa->sentringing = 0;
1157
					}
1164
					}
1158
					break;
1165
					break;
1159
				default:
1166
				default:
1160
					ast_debug(1, "Dunno what to do with control type %d\n", f->subclass.integer);
1167
					ast_debug(1, "Dunno what to do with control type %d\n", f->subclass.integer);
1161
				}
1168
				}
1162
			} else if (single) {
1169
			} else if (single) {
1163
				switch (f->frametype) {
1170
				switch (f->frametype) {
1164
					case AST_FRAME_VOICE:
1171
					case AST_FRAME_VOICE:
1165
					case AST_FRAME_IMAGE:
1172
					case AST_FRAME_IMAGE:
1166
					case AST_FRAME_TEXT:
1173
					case AST_FRAME_TEXT:
1167
						if (ast_write(in, f)) {
1174
						if (ast_write(in, f)) {
1168
							ast_log(LOG_WARNING, "Unable to write frame\n");
1175
							ast_log(LOG_WARNING, "Unable to write frame\n");
1169
						}
1176
						}
1170
						break;
1177
						break;
1171
					case AST_FRAME_HTML:
1178
					case AST_FRAME_HTML:
1172
						if (!ast_test_flag64(outgoing, DIAL_NOFORWARDHTML) && ast_channel_sendhtml(in, f->subclass.integer, f->data.ptr, f->datalen) == -1) {
1179
						if (!ast_test_flag64(outgoing, DIAL_NOFORWARDHTML) && ast_channel_sendhtml(in, f->subclass.integer, f->data.ptr, f->datalen) == -1) {
1173
							ast_log(LOG_WARNING, "Unable to send URL\n");
1180
							ast_log(LOG_WARNING, "Unable to send URL\n");
1174
						}
1181
						}
1175
						break;
1182
						break;
1176
					default:
1183
					default:
1177
						break;
1184
						break;
1178
				}
1185
				}
1179
			}
1186
			}
1180
			ast_frfree(f);
1187
			ast_frfree(f);
1181
		} /* end for */
1188
		} /* end for */
1182
		if (winner == in) {
1189
		if (winner == in) {
1183
			struct ast_frame *f = ast_read(in);
1190
			struct ast_frame *f = ast_read(in);
1184
#if 0
1191
#if 0
1185
			if (f && (f->frametype != AST_FRAME_VOICE))
1192
			if (f && (f->frametype != AST_FRAME_VOICE))
1186
				printf("Frame type: %d, %d\n", f->frametype, f->subclass);
1193
				printf("Frame type: %d, %d\n", f->frametype, f->subclass);
1187
			else if (!f || (f->frametype != AST_FRAME_VOICE))
1194
			else if (!f || (f->frametype != AST_FRAME_VOICE))
1188
				printf("Hangup received on %s\n", in->name);
1195
				printf("Hangup received on %s\n", in->name);
1189
#endif
1196
#endif
1190
			if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass.integer == AST_CONTROL_HANGUP))) {
1197
			if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass.integer == AST_CONTROL_HANGUP))) {
1191
				/* Got hung up */
1198
				/* Got hung up */
1192
				*to = -1;
1199
				*to = -1;
1193
				strcpy(pa->status, "CANCEL");
1200
				strcpy(pa->status, "CANCEL");
1194
				ast_cdr_noanswer(in->cdr);
1201
				ast_cdr_noanswer(in->cdr);
1195
				if (f) {
1202
				if (f) {
1196
					if (f->data.uint32) {
1203
					if (f->data.uint32) {
1197
						in->hangupcause = f->data.uint32;
1204
						in->hangupcause = f->data.uint32;
1198
					}
1205
					}
1199
					ast_frfree(f);
1206
					ast_frfree(f);
1200
				}
1207
				}
1201
				return NULL;
1208
				return NULL;
1202
			}
1209
			}
1203

    
   
1210

   
1204
			/* now f is guaranteed non-NULL */
1211
			/* now f is guaranteed non-NULL */
1205
			if (f->frametype == AST_FRAME_DTMF) {
1212
			if (f->frametype == AST_FRAME_DTMF) {
1206
				if (ast_test_flag64(peerflags, OPT_DTMF_EXIT)) {
1213
				if (ast_test_flag64(peerflags, OPT_DTMF_EXIT)) {
1207
					const char *context;
1214
					const char *context;
1208
					ast_channel_lock(in);
1215
					ast_channel_lock(in);
1209
					context = pbx_builtin_getvar_helper(in, "EXITCONTEXT");
1216
					context = pbx_builtin_getvar_helper(in, "EXITCONTEXT");
1210
					if (onedigit_goto(in, context, (char) f->subclass.integer, 1)) {
1217
					if (onedigit_goto(in, context, (char) f->subclass.integer, 1)) {
1211
						ast_verb(3, "User hit %c to disconnect call.\n", f->subclass.integer);
1218
						ast_verb(3, "User hit %c to disconnect call.\n", f->subclass.integer);
1212
						*to = 0;
1219
						*to = 0;
1213
						ast_cdr_noanswer(in->cdr);
1220
						ast_cdr_noanswer(in->cdr);
1214
						*result = f->subclass.integer;
1221
						*result = f->subclass.integer;
1215
						strcpy(pa->status, "CANCEL");
1222
						strcpy(pa->status, "CANCEL");
1216
						ast_frfree(f);
1223
						ast_frfree(f);
1217
						ast_channel_unlock(in);
1224
						ast_channel_unlock(in);
1218
						return NULL;
1225
						return NULL;
1219
					}
1226
					}
1220
					ast_channel_unlock(in);
1227
					ast_channel_unlock(in);
1221
				}
1228
				}
1222

    
   
1229

   
1223
				if (ast_test_flag64(peerflags, OPT_CALLER_HANGUP) &&
1230
				if (ast_test_flag64(peerflags, OPT_CALLER_HANGUP) &&
1224
					detect_disconnect(in, f->subclass.integer, featurecode)) {
1231
					detect_disconnect(in, f->subclass.integer, featurecode)) {
1225
					ast_verb(3, "User requested call disconnect.\n");
1232
					ast_verb(3, "User requested call disconnect.\n");
1226
					*to = 0;
1233
					*to = 0;
1227
					strcpy(pa->status, "CANCEL");
1234
					strcpy(pa->status, "CANCEL");
1228
					ast_cdr_noanswer(in->cdr);
1235
					ast_cdr_noanswer(in->cdr);
1229
					ast_frfree(f);
1236
					ast_frfree(f);
1230
					return NULL;
1237
					return NULL;
1231
				}
1238
				}
1232
			}
1239
			}
1233

    
   
1240

   
1234
			/* Forward HTML stuff */
1241
			/* Forward HTML stuff */
1235
			if (single && (f->frametype == AST_FRAME_HTML) && !ast_test_flag64(outgoing, DIAL_NOFORWARDHTML))
1242
			if (single && (f->frametype == AST_FRAME_HTML) && !ast_test_flag64(outgoing, DIAL_NOFORWARDHTML))
1236
				if (ast_channel_sendhtml(outgoing->chan, f->subclass.integer, f->data.ptr, f->datalen) == -1)
1243
				if (ast_channel_sendhtml(outgoing->chan, f->subclass.integer, f->data.ptr, f->datalen) == -1)
1237
					ast_log(LOG_WARNING, "Unable to send URL\n");
1244
					ast_log(LOG_WARNING, "Unable to send URL\n");
1238

    
   
1245

   
1239
			if (single && ((f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_DTMF_BEGIN) || (f->frametype == AST_FRAME_DTMF_END)))  {
1246
			if (single && ((f->frametype == AST_FRAME_VOICE) || (f->frametype == AST_FRAME_DTMF_BEGIN) || (f->frametype == AST_FRAME_DTMF_END)))  {
1240
				if (ast_write(outgoing->chan, f))
1247
				if (ast_write(outgoing->chan, f))
1241
					ast_log(LOG_WARNING, "Unable to forward voice or dtmf\n");
1248
					ast_log(LOG_WARNING, "Unable to forward voice or dtmf\n");
1242
			}
1249
			}
1243
			if (single && (f->frametype == AST_FRAME_CONTROL)) { 
1250
			if (single && (f->frametype == AST_FRAME_CONTROL)) { 
1244
				if ((f->subclass.integer == AST_CONTROL_HOLD) ||
1251
				if ((f->subclass.integer == AST_CONTROL_HOLD) ||
1245
				    (f->subclass.integer == AST_CONTROL_UNHOLD) ||
1252
				    (f->subclass.integer == AST_CONTROL_UNHOLD) ||
1246
				    (f->subclass.integer == AST_CONTROL_VIDUPDATE) ||
1253
				    (f->subclass.integer == AST_CONTROL_VIDUPDATE) ||
1247
				    (f->subclass.integer == AST_CONTROL_SRCUPDATE) ||
1254
				    (f->subclass.integer == AST_CONTROL_SRCUPDATE) ||
1248
				    (f->subclass.integer == AST_CONTROL_REDIRECTING)) {
1255
				    (f->subclass.integer == AST_CONTROL_REDIRECTING)) {
1249
					ast_verb(3, "%s requested special control %d, passing it to %s\n", in->name, f->subclass.integer, outgoing->chan->name);
1256
					ast_verb(3, "%s requested special control %d, passing it to %s\n", in->name, f->subclass.integer, outgoing->chan->name);
1250
					ast_indicate_data(outgoing->chan, f->subclass.integer, f->data.ptr, f->datalen);
1257
					ast_indicate_data(outgoing->chan, f->subclass.integer, f->data.ptr, f->datalen);
1251
				} else if (f->subclass.integer == AST_CONTROL_CONNECTED_LINE) {
1258
				} else if (f->subclass.integer == AST_CONTROL_CONNECTED_LINE) {
1252
					if (ast_channel_connected_line_macro(in, outgoing->chan, f, 0, 1)) {
1259
					if (ast_channel_connected_line_macro(in, outgoing->chan, f, 0, 1)) {
1253
						ast_indicate_data(outgoing->chan, f->subclass.integer, f->data.ptr, f->datalen);
1260
						ast_indicate_data(outgoing->chan, f->subclass.integer, f->data.ptr, f->datalen);
1254
					}
1261
					}
1255
				}
1262
				}
1256
			}
1263
			}
1257
			ast_frfree(f);
1264
			ast_frfree(f);
1258
		}
1265
		}
1259
		if (!*to)
1266
		if (!*to)
1260
			ast_verb(3, "Nobody picked up in %d ms\n", orig);
1267
			ast_verb(3, "Nobody picked up in %d ms\n", orig);
1261
		if (!*to || ast_check_hangup(in))
1268
		if (!*to || ast_check_hangup(in))
1262
			ast_cdr_noanswer(in->cdr);
1269
			ast_cdr_noanswer(in->cdr);
1263
	}
1270
	}
1264

    
   
1271

   
1265
#ifdef HAVE_EPOLL
1272
#ifdef HAVE_EPOLL
1266
	for (epollo = outgoing; epollo; epollo = epollo->next) {
1273
	for (epollo = outgoing; epollo; epollo = epollo->next) {
1267
		if (epollo->chan)
1274
		if (epollo->chan)
1268
			ast_poll_channel_del(in, epollo->chan);
1275
			ast_poll_channel_del(in, epollo->chan);
1269
	}
1276
	}
1270
#endif
1277
#endif
1271

    
   
1278

   
1272
	return peer;
1279
	return peer;
1273
}
1280
}
1274

    
   
1281

   
1275
static int detect_disconnect(struct ast_channel *chan, char code, struct ast_str *featurecode)
1282
static int detect_disconnect(struct ast_channel *chan, char code, struct ast_str *featurecode)
1276
{
1283
{
1277
	struct ast_flags features = { AST_FEATURE_DISCONNECT }; /* only concerned with disconnect feature */
1284
	struct ast_flags features = { AST_FEATURE_DISCONNECT }; /* only concerned with disconnect feature */
1278
	struct ast_call_feature feature = { 0, };
1285
	struct ast_call_feature feature = { 0, };
1279
	int res;
1286
	int res;
1280

    
   
1287

   
1281
	ast_str_append(&featurecode, 1, "%c", code);
1288
	ast_str_append(&featurecode, 1, "%c", code);
1282

    
   
1289

   
1283
	res = ast_feature_detect(chan, &features, ast_str_buffer(featurecode), &feature);
1290
	res = ast_feature_detect(chan, &features, ast_str_buffer(featurecode), &feature);
1284

    
   
1291

   
1285
	if (res != AST_FEATURE_RETURN_STOREDIGITS) {
1292
	if (res != AST_FEATURE_RETURN_STOREDIGITS) {
1286
		ast_str_reset(featurecode);
1293
		ast_str_reset(featurecode);
1287
	}
1294
	}
1288
	if (feature.feature_mask & AST_FEATURE_DISCONNECT) {
1295
	if (feature.feature_mask & AST_FEATURE_DISCONNECT) {
1289
		return 1;
1296
		return 1;
1290
	}
1297
	}
1291

    
   
1298

   
1292
	return 0;
1299
	return 0;
1293
}
1300
}
1294

    
   
1301

   
1295
static void replace_macro_delimiter(char *s)
1302
static void replace_macro_delimiter(char *s)
1296
{
1303
{
1297
	for (; *s; s++)
1304
	for (; *s; s++)
1298
		if (*s == '^')
1305
		if (*s == '^')
1299
			*s = ',';
1306
			*s = ',';
1300
}
1307
}
1301

    
   
1308

   
1302
/* returns true if there is a valid privacy reply */
1309
/* returns true if there is a valid privacy reply */
1303
static int valid_priv_reply(struct ast_flags64 *opts, int res)
1310
static int valid_priv_reply(struct ast_flags64 *opts, int res)
1304
{
1311
{
1305
	if (res < '1')
1312
	if (res < '1')
1306
		return 0;
1313
		return 0;
1307
	if (ast_test_flag64(opts, OPT_PRIVACY) && res <= '5')
1314
	if (ast_test_flag64(opts, OPT_PRIVACY) && res <= '5')
1308
		return 1;
1315
		return 1;
1309
	if (ast_test_flag64(opts, OPT_SCREENING) && res <= '4')
1316
	if (ast_test_flag64(opts, OPT_SCREENING) && res <= '4')
1310
		return 1;
1317
		return 1;
1311
	return 0;
1318
	return 0;
1312
}
1319
}
1313

    
   
1320

   
1314
static int do_privacy(struct ast_channel *chan, struct ast_channel *peer,
1321
static int do_privacy(struct ast_channel *chan, struct ast_channel *peer,
1315
	struct ast_flags64 *opts, char **opt_args, struct privacy_args *pa)
1322
	struct ast_flags64 *opts, char **opt_args, struct privacy_args *pa)
1316
{
1323
{
1317

    
   
1324

   
1318
	int res2;
1325
	int res2;
1319
	int loopcount = 0;
1326
	int loopcount = 0;
1320

    
   
1327

   
1321
	/* Get the user's intro, store it in priv-callerintros/$CID,
1328
	/* Get the user's intro, store it in priv-callerintros/$CID,
1322
	   unless it is already there-- this should be done before the
1329
	   unless it is already there-- this should be done before the
1323
	   call is actually dialed  */
1330
	   call is actually dialed  */
1324

    
   
1331

   
1325
	/* all ring indications and moh for the caller has been halted as soon as the
1332
	/* all ring indications and moh for the caller has been halted as soon as the
1326
	   target extension was picked up. We are going to have to kill some
1333
	   target extension was picked up. We are going to have to kill some
1327
	   time and make the caller believe the peer hasn't picked up yet */
1334
	   time and make the caller believe the peer hasn't picked up yet */
1328

    
   
1335

   
1329
	if (ast_test_flag64(opts, OPT_MUSICBACK) && !ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
1336
	if (ast_test_flag64(opts, OPT_MUSICBACK) && !ast_strlen_zero(opt_args[OPT_ARG_MUSICBACK])) {
1330
		char *original_moh = ast_strdupa(chan->musicclass);
1337
		char *original_moh = ast_strdupa(chan->musicclass);
1331
		ast_indicate(chan, -1);
1338
		ast_indicate(chan, -1);
1332
		ast_string_field_set(chan, musicclass, opt_args[OPT_ARG_MUSICBACK]);
1339
		ast_string_field_set(chan, musicclass, opt_args[OPT_ARG_MUSICBACK]);
1333
		ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
1340
		ast_moh_start(chan, opt_args[OPT_ARG_MUSICBACK], NULL);
1334
		ast_string_field_set(chan, musicclass, original_moh);
1341
		ast_string_field_set(chan, musicclass, original_moh);
1335
	} else if (ast_test_flag64(opts, OPT_RINGBACK)) {
1342
	} else if (ast_test_flag64(opts, OPT_RINGBACK)) {
1336
		ast_indicate(chan, AST_CONTROL_RINGING);
1343
		ast_indicate(chan, AST_CONTROL_RINGING);
1337
		pa->sentringing++;
1344
		pa->sentringing++;
1338
	}
1345
	}
1339

    
   
1346

   
1340
	/* Start autoservice on the other chan ?? */
1347
	/* Start autoservice on the other chan ?? */
1341
	res2 = ast_autoservice_start(chan);
1348
	res2 = ast_autoservice_start(chan);
1342
	/* Now Stream the File */
1349
	/* Now Stream the File */
1343
	for (loopcount = 0; loopcount < 3; loopcount++) {
1350
	for (loopcount = 0; loopcount < 3; loopcount++) {
1344
		if (res2 && loopcount == 0) /* error in ast_autoservice_start() */
1351
		if (res2 && loopcount == 0) /* error in ast_autoservice_start() */
1345
			break;
1352
			break;
1346
		if (!res2) /* on timeout, play the message again */
1353
		if (!res2) /* on timeout, play the message again */
1347
			res2 = ast_play_and_wait(peer, "priv-callpending");
1354
			res2 = ast_play_and_wait(peer, "priv-callpending");
1348
		if (!valid_priv_reply(opts, res2))
1355
		if (!valid_priv_reply(opts, res2))
1349
			res2 = 0;
1356
			res2 = 0;
1350
		/* priv-callpending script:
1357
		/* priv-callpending script:
1351
		   "I have a caller waiting, who introduces themselves as:"
1358
		   "I have a caller waiting, who introduces themselves as:"
1352
		*/
1359
		*/
1353
		if (!res2)
1360
		if (!res2)
1354
			res2 = ast_play_and_wait(peer, pa->privintro);
1361
			res2 = ast_play_and_wait(peer, pa->privintro);
1355
		if (!valid_priv_reply(opts, res2))
1362
		if (!valid_priv_reply(opts, res2))
1356
			res2 = 0;
1363
			res2 = 0;
1357
		/* now get input from the called party, as to their choice */
1364
		/* now get input from the called party, as to their choice */
1358
		if (!res2) {
1365
		if (!res2) {
1359
			/* XXX can we have both, or they are mutually exclusive ? */
1366
			/* XXX can we have both, or they are mutually exclusive ? */
1360
			if (ast_test_flag64(opts, OPT_PRIVACY))
1367
			if (ast_test_flag64(opts, OPT_PRIVACY))
1361
				res2 = ast_play_and_wait(peer, "priv-callee-options");
1368
				res2 = ast_play_and_wait(peer, "priv-callee-options");
1362
			if (ast_test_flag64(opts, OPT_SCREENING))
1369
			if (ast_test_flag64(opts, OPT_SCREENING))
1363
				res2 = ast_play_and_wait(peer, "screen-callee-options");
1370
				res2 = ast_play_and_wait(peer, "screen-callee-options");
1364
		}
1371
		}
1365
		/*! \page DialPrivacy Dial Privacy scripts
1372
		/*! \page DialPrivacy Dial Privacy scripts
1366
		\par priv-callee-options script:
1373
		\par priv-callee-options script:
1367
			"Dial 1 if you wish this caller to reach you directly in the future,
1374
			"Dial 1 if you wish this caller to reach you directly in the future,
1368
				and immediately connect to their incoming call
1375
				and immediately connect to their incoming call
1369
			 Dial 2 if you wish to send this caller to voicemail now and
1376
			 Dial 2 if you wish to send this caller to voicemail now and
1370
				forevermore.
1377
				forevermore.
1371
			 Dial 3 to send this caller to the torture menus, now and forevermore.
1378
			 Dial 3 to send this caller to the torture menus, now and forevermore.
1372
			 Dial 4 to send this caller to a simple "go away" menu, now and forevermore.
1379
			 Dial 4 to send this caller to a simple "go away" menu, now and forevermore.
1373
			 Dial 5 to allow this caller to come straight thru to you in the future,
1380
			 Dial 5 to allow this caller to come straight thru to you in the future,
1374
				but right now, just this once, send them to voicemail."
1381
				but right now, just this once, send them to voicemail."
1375
		\par screen-callee-options script:
1382
		\par screen-callee-options script:
1376
			"Dial 1 if you wish to immediately connect to the incoming call
1383
			"Dial 1 if you wish to immediately connect to the incoming call
1377
			 Dial 2 if you wish to send this caller to voicemail.
1384
			 Dial 2 if you wish to send this caller to voicemail.
1378
			 Dial 3 to send this caller to the torture menus.
1385
			 Dial 3 to send this caller to the torture menus.
1379
			 Dial 4 to send this caller to a simple "go away" menu.
1386
			 Dial 4 to send this caller to a simple "go away" menu.
1380
		*/
1387
		*/
1381
		if (valid_priv_reply(opts, res2))
1388
		if (valid_priv_reply(opts, res2))
1382
			break;
1389
			break;
1383
		/* invalid option */
1390
		/* invalid option */
1384
		res2 = ast_play_and_wait(peer, "vm-sorry");
1391
		res2 = ast_play_and_wait(peer, "vm-sorry");
1385
	}
1392
	}
1386

    
   
1393

   
1387
	if (ast_test_flag64(opts, OPT_MUSICBACK)) {
1394
	if (ast_test_flag64(opts, OPT_MUSICBACK)) {
1388
		ast_moh_stop(chan);
1395
		ast_moh_stop(chan);
1389
	} else if (ast_test_flag64(opts, OPT_RINGBACK)) {
1396
	} else if (ast_test_flag64(opts, OPT_RINGBACK)) {
1390
		ast_indicate(chan, -1);
1397
		ast_indicate(chan, -1);
1391
		pa->sentringing = 0;
1398
		pa->sentringing = 0;
1392
	}
1399
	}
1393
	ast_autoservice_stop(chan);
1400
	ast_autoservice_stop(chan);
1394
	if (ast_test_flag64(opts, OPT_PRIVACY) && (res2 >= '1' && res2 <= '5')) {
1401
	if (ast_test_flag64(opts, OPT_PRIVACY) && (res2 >= '1' && res2 <= '5')) {
1395
		/* map keypresses to various things, the index is res2 - '1' */
1402
		/* map keypresses to various things, the index is res2 - '1' */
1396
		static const char * const _val[] = { "ALLOW", "DENY", "TORTURE", "KILL", "ALLOW" };
1403
		static const char * const _val[] = { "ALLOW", "DENY", "TORTURE", "KILL", "ALLOW" };
1397
		static const int _flag[] = { AST_PRIVACY_ALLOW, AST_PRIVACY_DENY, AST_PRIVACY_TORTURE, AST_PRIVACY_KILL, AST_PRIVACY_ALLOW};
1404
		static const int _flag[] = { AST_PRIVACY_ALLOW, AST_PRIVACY_DENY, AST_PRIVACY_TORTURE, AST_PRIVACY_KILL, AST_PRIVACY_ALLOW};
1398
		int i = res2 - '1';
1405
		int i = res2 - '1';
1399
		ast_verb(3, "--Set privacy database entry %s/%s to %s\n",
1406
		ast_verb(3, "--Set privacy database entry %s/%s to %s\n",
1400
			opt_args[OPT_ARG_PRIVACY], pa->privcid, _val[i]);
1407
			opt_args[OPT_ARG_PRIVACY], pa->privcid, _val[i]);
1401
		ast_privacy_set(opt_args[OPT_ARG_PRIVACY], pa->privcid, _flag[i]);
1408
		ast_privacy_set(opt_args[OPT_ARG_PRIVACY], pa->privcid, _flag[i]);
1402
	}
1409
	}
1403
	switch (res2) {
1410
	switch (res2) {
1404
	case '1':
1411
	case '1':
1405
		break;
1412
		break;
1406
	case '2':
1413
	case '2':
1407
		ast_copy_string(pa->status, "NOANSWER", sizeof(pa->status));
1414
		ast_copy_string(pa->status, "NOANSWER", sizeof(pa->status));
1408
		break;
1415
		break;
1409
	case '3':
1416
	case '3':
1410
		ast_copy_string(pa->status, "TORTURE", sizeof(pa->status));
1417
		ast_copy_string(pa->status, "TORTURE", sizeof(pa->status));
1411
		break;
1418
		break;
1412
	case '4':
1419
	case '4':
1413
		ast_copy_string(pa->status, "DONTCALL", sizeof(pa->status));
1420
		ast_copy_string(pa->status, "DONTCALL", sizeof(pa->status));
1414
		break;
1421
		break;
1415
	case '5':
1422
	case '5':
1416
		/* XXX should we set status to DENY ? */
1423
		/* XXX should we set status to DENY ? */
1417
		if (ast_test_flag64(opts, OPT_PRIVACY))
1424
		if (ast_test_flag64(opts, OPT_PRIVACY))
1418
			break;
1425
			break;
1419
		/* if not privacy, then 5 is the same as "default" case */
1426
		/* if not privacy, then 5 is the same as "default" case */
1420
	default: /* bad input or -1 if failure to start autoservice */
1427
	default: /* bad input or -1 if failure to start autoservice */
1421
		/* well, if the user messes up, ... he had his chance... What Is The Best Thing To Do?  */
1428
		/* well, if the user messes up, ... he had his chance... What Is The Best Thing To Do?  */
1422
		/* well, there seems basically two choices. Just patch the caller thru immediately,
1429
		/* well, there seems basically two choices. Just patch the caller thru immediately,
1423
			  or,... put 'em thru to voicemail. */
1430
			  or,... put 'em thru to voicemail. */
1424
		/* since the callee may have hung up, let's do the voicemail thing, no database decision */
1431
		/* since the callee may have hung up, let's do the voicemail thing, no database decision */
1425
		ast_log(LOG_NOTICE, "privacy: no valid response from the callee. Sending the caller to voicemail, the callee isn't responding\n");
1432
		ast_log(LOG_NOTICE, "privacy: no valid response from the callee. Sending the caller to voicemail, the callee isn't responding\n");
1426
		/* XXX should we set status to DENY ? */
1433
		/* XXX should we set status to DENY ? */
1427
		/* XXX what about the privacy flags ? */
1434
		/* XXX what about the privacy flags ? */
1428
		break;
1435
		break;
1429
	}
1436
	}
1430

    
   
1437

   
1431
	if (res2 == '1') { /* the only case where we actually connect */
1438
	if (res2 == '1') { /* the only case where we actually connect */
1432
		/* if the intro is NOCALLERID, then there's no reason to leave it on disk, it'll
1439
		/* if the intro is NOCALLERID, then there's no reason to leave it on disk, it'll
1433
		   just clog things up, and it's not useful information, not being tied to a CID */
1440
		   just clog things up, and it's not useful information, not being tied to a CID */
1434
		if (strncmp(pa->privcid, "NOCALLERID", 10) == 0 || ast_test_flag64(opts, OPT_SCREEN_NOINTRO)) {
1441
		if (strncmp(pa->privcid, "NOCALLERID", 10) == 0 || ast_test_flag64(opts, OPT_SCREEN_NOINTRO)) {
1435
			ast_filedelete(pa->privintro, NULL);
1442
			ast_filedelete(pa->privintro, NULL);
1436
			if (ast_fileexists(pa->privintro, NULL, NULL) > 0)
1443
			if (ast_fileexists(pa->privintro, NULL, NULL) > 0)
1437
				ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", pa->privintro);
1444
				ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", pa->privintro);
1438
			else
1445
			else
1439
				ast_verb(3, "Successfully deleted %s intro file\n", pa->privintro);
1446
				ast_verb(3, "Successfully deleted %s intro file\n", pa->privintro);
1440
		}
1447
		}
1441
		return 0; /* the good exit path */
1448
		return 0; /* the good exit path */
1442
	} else {
1449
	} else {
1443
		ast_hangup(peer); /* hang up on the callee -- he didn't want to talk anyway! */
1450
		ast_hangup(peer); /* hang up on the callee -- he didn't want to talk anyway! */
1444
		return -1;
1451
		return -1;
1445
	}
1452
	}
1446
}
1453
}
1447

    
   
1454

   
1448
/*! \brief returns 1 if successful, 0 or <0 if the caller should 'goto out' */
1455
/*! \brief returns 1 if successful, 0 or <0 if the caller should 'goto out' */
1449
static int setup_privacy_args(struct privacy_args *pa,
1456
static int setup_privacy_args(struct privacy_args *pa,
1450
	struct ast_flags64 *opts, char *opt_args[], struct ast_channel *chan)
1457
	struct ast_flags64 *opts, char *opt_args[], struct ast_channel *chan)
1451
{
1458
{
1452
	char callerid[60];
1459
	char callerid[60];
1453
	int res;
1460
	int res;
1454
	char *l;
1461
	char *l;
1455
	int silencethreshold;
1462
	int silencethreshold;
1456

    
   
1463

   
1457
	if (!ast_strlen_zero(chan->cid.cid_num)) {
1464
	if (!ast_strlen_zero(chan->cid.cid_num)) {
1458
		l = ast_strdupa(chan->cid.cid_num);
1465
		l = ast_strdupa(chan->cid.cid_num);
1459
		ast_shrink_phone_number(l);
1466
		ast_shrink_phone_number(l);
1460
		if (ast_test_flag64(opts, OPT_PRIVACY) ) {
1467
		if (ast_test_flag64(opts, OPT_PRIVACY) ) {
1461
			ast_verb(3, "Privacy DB is '%s', clid is '%s'\n", opt_args[OPT_ARG_PRIVACY], l);
1468
			ast_verb(3, "Privacy DB is '%s', clid is '%s'\n", opt_args[OPT_ARG_PRIVACY], l);
1462
			pa->privdb_val = ast_privacy_check(opt_args[OPT_ARG_PRIVACY], l);
1469
			pa->privdb_val = ast_privacy_check(opt_args[OPT_ARG_PRIVACY], l);
1463
		} else {
1470
		} else {
1464
			ast_verb(3, "Privacy Screening, clid is '%s'\n", l);
1471
			ast_verb(3, "Privacy Screening, clid is '%s'\n", l);
1465
			pa->privdb_val = AST_PRIVACY_UNKNOWN;
1472
			pa->privdb_val = AST_PRIVACY_UNKNOWN;
1466
		}
1473
		}
1467
	} else {
1474
	} else {
1468
		char *tnam, *tn2;
1475
		char *tnam, *tn2;
1469

    
   
1476

   
1470
		tnam = ast_strdupa(chan->name);
1477
		tnam = ast_strdupa(chan->name);
1471
		/* clean the channel name so slashes don't try to end up in disk file name */
1478
		/* clean the channel name so slashes don't try to end up in disk file name */
1472
		for (tn2 = tnam; *tn2; tn2++) {
1479
		for (tn2 = tnam; *tn2; tn2++) {
1473
			if (*tn2 == '/')  /* any other chars to be afraid of? */
1480
			if (*tn2 == '/')  /* any other chars to be afraid of? */
1474
				*tn2 = '=';
1481
				*tn2 = '=';
1475
		}
1482
		}
1476
		ast_verb(3, "Privacy-- callerid is empty\n");
1483
		ast_verb(3, "Privacy-- callerid is empty\n");
1477

    
   
1484

   
1478
		snprintf(callerid, sizeof(callerid), "NOCALLERID_%s%s", chan->exten, tnam);
1485
		snprintf(callerid, sizeof(callerid), "NOCALLERID_%s%s", chan->exten, tnam);
1479
		l = callerid;
1486
		l = callerid;
1480
		pa->privdb_val = AST_PRIVACY_UNKNOWN;
1487
		pa->privdb_val = AST_PRIVACY_UNKNOWN;
1481
	}
1488
	}
1482

    
   
1489

   
1483
	ast_copy_string(pa->privcid, l, sizeof(pa->privcid));
1490
	ast_copy_string(pa->privcid, l, sizeof(pa->privcid));
1484

    
   
1491

   
1485
	if (strncmp(pa->privcid, "NOCALLERID", 10) != 0 && ast_test_flag64(opts, OPT_SCREEN_NOCALLERID)) {
1492
	if (strncmp(pa->privcid, "NOCALLERID", 10) != 0 && ast_test_flag64(opts, OPT_SCREEN_NOCALLERID)) {
1486
		/* if callerid is set and OPT_SCREEN_NOCALLERID is set also */
1493
		/* if callerid is set and OPT_SCREEN_NOCALLERID is set also */
1487
		ast_verb(3, "CallerID set (%s); N option set; Screening should be off\n", pa->privcid);
1494
		ast_verb(3, "CallerID set (%s); N option set; Screening should be off\n", pa->privcid);
1488
		pa->privdb_val = AST_PRIVACY_ALLOW;
1495
		pa->privdb_val = AST_PRIVACY_ALLOW;
1489
	} else if (ast_test_flag64(opts, OPT_SCREEN_NOCALLERID) && strncmp(pa->privcid, "NOCALLERID", 10) == 0) {
1496
	} else if (ast_test_flag64(opts, OPT_SCREEN_NOCALLERID) && strncmp(pa->privcid, "NOCALLERID", 10) == 0) {
1490
		ast_verb(3, "CallerID blank; N option set; Screening should happen; dbval is %d\n", pa->privdb_val);
1497
		ast_verb(3, "CallerID blank; N option set; Screening should happen; dbval is %d\n", pa->privdb_val);
1491
	}
1498
	}
1492
	
1499
	
1493
	if (pa->privdb_val == AST_PRIVACY_DENY) {
1500
	if (pa->privdb_val == AST_PRIVACY_DENY) {
1494
		ast_verb(3, "Privacy DB reports PRIVACY_DENY for this callerid. Dial reports unavailable\n");
1501
		ast_verb(3, "Privacy DB reports PRIVACY_DENY for this callerid. Dial reports unavailable\n");
1495
		ast_copy_string(pa->status, "NOANSWER", sizeof(pa->status));
1502
		ast_copy_string(pa->status, "NOANSWER", sizeof(pa->status));
1496
		return 0;
1503
		return 0;
1497
	} else if (pa->privdb_val == AST_PRIVACY_KILL) {
1504
	} else if (pa->privdb_val == AST_PRIVACY_KILL) {
1498
		ast_copy_string(pa->status, "DONTCALL", sizeof(pa->status));
1505
		ast_copy_string(pa->status, "DONTCALL", sizeof(pa->status));
1499
		return 0; /* Is this right? */
1506
		return 0; /* Is this right? */
1500
	} else if (pa->privdb_val == AST_PRIVACY_TORTURE) {
1507
	} else if (pa->privdb_val == AST_PRIVACY_TORTURE) {
1501
		ast_copy_string(pa->status, "TORTURE", sizeof(pa->status));
1508
		ast_copy_string(pa->status, "TORTURE", sizeof(pa->status));
1502
		return 0; /* is this right??? */
1509
		return 0; /* is this right??? */
1503
	} else if (pa->privdb_val == AST_PRIVACY_UNKNOWN) {
1510
	} else if (pa->privdb_val == AST_PRIVACY_UNKNOWN) {
1504
		/* Get the user's intro, store it in priv-callerintros/$CID,
1511
		/* Get the user's intro, store it in priv-callerintros/$CID,
1505
		   unless it is already there-- this should be done before the
1512
		   unless it is already there-- this should be done before the
1506
		   call is actually dialed  */
1513
		   call is actually dialed  */
1507

    
   
1514

   
1508
		/* make sure the priv-callerintros dir actually exists */
1515
		/* make sure the priv-callerintros dir actually exists */
1509
		snprintf(pa->privintro, sizeof(pa->privintro), "%s/sounds/priv-callerintros", ast_config_AST_DATA_DIR);
1516
		snprintf(pa->privintro, sizeof(pa->privintro), "%s/sounds/priv-callerintros", ast_config_AST_DATA_DIR);
1510
		if ((res = ast_mkdir(pa->privintro, 0755))) {
1517
		if ((res = ast_mkdir(pa->privintro, 0755))) {
1511
			ast_log(LOG_WARNING, "privacy: can't create directory priv-callerintros: %s\n", strerror(res));
1518
			ast_log(LOG_WARNING, "privacy: can't create directory priv-callerintros: %s\n", strerror(res));
1512
			return -1;
1519
			return -1;
1513
		}
1520
		}
1514

    
   
1521

   
1515
		snprintf(pa->privintro, sizeof(pa->privintro), "priv-callerintros/%s", pa->privcid);
1522
		snprintf(pa->privintro, sizeof(pa->privintro), "priv-callerintros/%s", pa->privcid);
1516
		if (ast_fileexists(pa->privintro, NULL, NULL ) > 0 && strncmp(pa->privcid, "NOCALLERID", 10) != 0) {
1523
		if (ast_fileexists(pa->privintro, NULL, NULL ) > 0 && strncmp(pa->privcid, "NOCALLERID", 10) != 0) {
1517
			/* the DELUX version of this code would allow this caller the
1524
			/* the DELUX version of this code would allow this caller the
1518
			   option to hear and retape their previously recorded intro.
1525
			   option to hear and retape their previously recorded intro.
1519
			*/
1526
			*/
1520
		} else {
1527
		} else {
1521
			int duration; /* for feedback from play_and_wait */
1528
			int duration; /* for feedback from play_and_wait */
1522
			/* the file doesn't exist yet. Let the caller submit his
1529
			/* the file doesn't exist yet. Let the caller submit his
1523
			   vocal intro for posterity */
1530
			   vocal intro for posterity */
1524
			/* priv-recordintro script:
1531
			/* priv-recordintro script:
1525

    
   
1532

   
1526
			   "At the tone, please say your name:"
1533
			   "At the tone, please say your name:"
1527

    
   
1534

   
1528
			*/
1535
			*/
1529
			silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE);
1536
			silencethreshold = ast_dsp_get_threshold_from_settings(THRESHOLD_SILENCE);
1530
			ast_answer(chan);
1537
			ast_answer(chan);
1531
			res = ast_play_and_record(chan, "priv-recordintro", pa->privintro, 4, "gsm", &duration, silencethreshold, 2000, 0);  /* NOTE: I've reduced the total time to 4 sec */
1538
			res = ast_play_and_record(chan, "priv-recordintro", pa->privintro, 4, "gsm", &duration, silencethreshold, 2000, 0);  /* NOTE: I've reduced the total time to 4 sec */
1532
									/* don't think we'll need a lock removed, we took care of
1539
									/* don't think we'll need a lock removed, we took care of
1533
									   conflicts by naming the pa.privintro file */
1540
									   conflicts by naming the pa.privintro file */
1534
			if (res == -1) {
1541
			if (res == -1) {
1535
				/* Delete the file regardless since they hung up during recording */
1542
				/* Delete the file regardless since they hung up during recording */
1536
				ast_filedelete(pa->privintro, NULL);
1543
				ast_filedelete(pa->privintro, NULL);
1537
				if (ast_fileexists(pa->privintro, NULL, NULL) > 0)
1544
				if (ast_fileexists(pa->privintro, NULL, NULL) > 0)
1538
					ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", pa->privintro);
1545
					ast_log(LOG_NOTICE, "privacy: ast_filedelete didn't do its job on %s\n", pa->privintro);
1539
				else
1546
				else
1540
					ast_verb(3, "Successfully deleted %s intro file\n", pa->privintro);
1547
					ast_verb(3, "Successfully deleted %s intro file\n", pa->privintro);
1541
				return -1;
1548
				return -1;
1542
			}
1549
			}
1543
			if (!ast_streamfile(chan, "vm-dialout", chan->language) )
1550
			if (!ast_streamfile(chan, "vm-dialout", chan->language) )
1544
				ast_waitstream(chan, "");
1551
				ast_waitstream(chan, "");
1545
		}
1552
		}
1546
	}
1553
	}
1547
	return 1; /* success */
1554
	return 1; /* success */
1548
}
1555
}
1549

    
   
1556

   
1550
static void end_bridge_callback(void *data)
1557
static void end_bridge_callback(void *data)
1551
{
1558
{
1552
	char buf[80];
1559
	char buf[80];
1553
	time_t end;
1560
	time_t end;
1554
	struct ast_channel *chan = data;
1561
	struct ast_channel *chan = data;
1555

    
   
1562

   
1556
	if (!chan->cdr) {
1563
	if (!chan->cdr) {
1557
		return;
1564
		return;
1558
	}
1565
	}
1559

    
   
1566

   
1560
	time(&end);
1567
	time(&end);
1561

    
   
1568

   
1562
	ast_channel_lock(chan);
1569
	ast_channel_lock(chan);
1563
	if (chan->cdr->answer.tv_sec) {
1570
	if (chan->cdr->answer.tv_sec) {
1564
		snprintf(buf, sizeof(buf), "%ld", end - chan->cdr->answer.tv_sec);
1571
		snprintf(buf, sizeof(buf), "%ld", end - chan->cdr->answer.tv_sec);
1565
		pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", buf);
1572
		pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", buf);
1566
	}
1573
	}
1567

    
   
1574

   
1568
	if (chan->cdr->start.tv_sec) {
1575
	if (chan->cdr->start.tv_sec) {
1569
		snprintf(buf, sizeof(buf), "%ld", end - chan->cdr->start.tv_sec);
1576
		snprintf(buf, sizeof(buf), "%ld", end - chan->cdr->start.tv_sec);
1570
		pbx_builtin_setvar_helper(chan, "DIALEDTIME", buf);
1577
		pbx_builtin_setvar_helper(chan, "DIALEDTIME", buf);
1571
	}
1578
	}
1572
	ast_channel_unlock(chan);
1579
	ast_channel_unlock(chan);
1573
}
1580
}
1574

    
   
1581

   
1575
static void end_bridge_callback_data_fixup(struct ast_bridge_config *bconfig, struct ast_channel *originator, struct ast_channel *terminator) {
1582
static void end_bridge_callback_data_fixup(struct ast_bridge_config *bconfig, struct ast_channel *originator, struct ast_channel *terminator) {
1576
	bconfig->end_bridge_callback_data = originator;
1583
	bconfig->end_bridge_callback_data = originator;
1577
}
1584
}
1578

    
   
1585

   

    
   
1586
static int dial_handle_playtones(struct ast_channel *chan, const char *data)

    
   
1587
{

    
   
1588
	struct ast_tone_zone_sound *ts = NULL;

    
   
1589
	int res;

    
   
1590
	const char *str = data;

    
   
1591

   

    
   
1592
	if (ast_strlen_zero(str)) {

    
   
1593
		ast_debug(1,"Nothing to play\n");

    
   
1594
		return -1;

    
   
1595
	}

    
   
1596

   

    
   
1597
	ts = ast_get_indication_tone(chan->zone, str);

    
   
1598

   

    
   
1599
	if (ts && ts->data[0]) {

    
   
1600
		res = ast_playtones_start(chan, 0, ts->data, 0);

    
   
1601
	} else {

    
   
1602
		res = -1;

    
   
1603
	}

    
   
1604

   

    
   
1605
	if (ts) {

    
   
1606
		ts = ast_tone_zone_sound_unref(ts);

    
   
1607
	}

    
   
1608

   

    
   
1609
	if (res) {

    
   
1610
		ast_log(LOG_WARNING, "Unable to start playtone \'%s\'\n", str);

    
   
1611
	}

    
   
1612

   

    
   
1613
	return res;

    
   
1614
}

    
   
1615

   
1579
static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast_flags64 *peerflags, int *continue_exec)
1616
static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast_flags64 *peerflags, int *continue_exec)
1580
{
1617
{
1581
	int res = -1; /* default: error */
1618
	int res = -1; /* default: error */
1582
	char *rest, *cur; /* scan the list of destinations */
1619
	char *rest, *cur; /* scan the list of destinations */
1583
	struct chanlist *outgoing = NULL; /* list of destinations */
1620
	struct chanlist *outgoing = NULL; /* list of destinations */
1584
	struct ast_channel *peer;
1621
	struct ast_channel *peer;
1585
	int to; /* timeout */
1622
	int to; /* timeout */
1586
	struct cause_args num = { chan, 0, 0, 0 };
1623
	struct cause_args num = { chan, 0, 0, 0 };
1587
	int cause;
1624
	int cause;
1588
	char numsubst[256];
1625
	char numsubst[256];
1589
	char cidname[AST_MAX_EXTENSION] = "";
1626
	char cidname[AST_MAX_EXTENSION] = "";
1590

    
   
1627

   
1591
	struct ast_bridge_config config = { { 0, } };
1628
	struct ast_bridge_config config = { { 0, } };
1592
	struct timeval calldurationlimit = { 0, };
1629
	struct timeval calldurationlimit = { 0, };
1593
	char *dtmfcalled = NULL, *dtmfcalling = NULL, *dtmf_progress=NULL;
1630
	char *dtmfcalled = NULL, *dtmfcalling = NULL, *dtmf_progress=NULL;
1594
	struct privacy_args pa = {
1631
	struct privacy_args pa = {
1595
		.sentringing = 0,
1632
		.sentringing = 0,
1596
		.privdb_val = 0,
1633
		.privdb_val = 0,
1597
		.status = "INVALIDARGS",
1634
		.status = "INVALIDARGS",
1598
	};
1635
	};
1599
	int sentringing = 0, moh = 0;
1636
	int sentringing = 0, moh = 0;
1600
	const char *outbound_group = NULL;
1637
	const char *outbound_group = NULL;
1601
	int result = 0;
1638
	int result = 0;
1602
	char *parse;
1639
	char *parse;
1603
	int opermode = 0;
1640
	int opermode = 0;
1604
	int delprivintro = 0;
1641
	int delprivintro = 0;
1605
	AST_DECLARE_APP_ARGS(args,
1642
	AST_DECLARE_APP_ARGS(args,
1606
		AST_APP_ARG(peers);
1643
		AST_APP_ARG(peers);
1607
		AST_APP_ARG(timeout);
1644
		AST_APP_ARG(timeout);
1608
		AST_APP_ARG(options);
1645
		AST_APP_ARG(options);
1609
		AST_APP_ARG(url);
1646
		AST_APP_ARG(url);
1610
	);
1647
	);
1611
	struct ast_flags64 opts = { 0, };
1648
	struct ast_flags64 opts = { 0, };
1612
	char *opt_args[OPT_ARG_ARRAY_SIZE];
1649
	char *opt_args[OPT_ARG_ARRAY_SIZE];
1613
	struct ast_datastore *datastore = NULL;
1650
	struct ast_datastore *datastore = NULL;
1614
	int fulldial = 0, num_dialed = 0;
1651
	int fulldial = 0, num_dialed = 0;
1615

    
   
1652

   
1616
	/* Reset all DIAL variables back to blank, to prevent confusion (in case we don't reset all of them). */
1653
	/* Reset all DIAL variables back to blank, to prevent confusion (in case we don't reset all of them). */
1617
	pbx_builtin_setvar_helper(chan, "DIALSTATUS", "");
1654
	pbx_builtin_setvar_helper(chan, "DIALSTATUS", "");
1618
	pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", "");
1655
	pbx_builtin_setvar_helper(chan, "DIALEDPEERNUMBER", "");
1619
	pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", "");
1656
	pbx_builtin_setvar_helper(chan, "DIALEDPEERNAME", "");
1620
	pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", "");
1657
	pbx_builtin_setvar_helper(chan, "ANSWEREDTIME", "");
1621
	pbx_builtin_setvar_helper(chan, "DIALEDTIME", "");
1658
	pbx_builtin_setvar_helper(chan, "DIALEDTIME", "");
1622

    
   
1659

   
1623
	if (ast_strlen_zero(data)) {
1660
	if (ast_strlen_zero(data)) {
1624
		ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
1661
		ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
1625
		pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
1662
		pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
1626
		return -1;
1663
		return -1;
1627
	}
1664
	}
1628

    
   
1665

   
1629
	parse = ast_strdupa(data);
1666
	parse = ast_strdupa(data);
1630

    
   
1667

   
1631
	AST_STANDARD_APP_ARGS(args, parse);
1668
	AST_STANDARD_APP_ARGS(args, parse);
1632

    
   
1669

   
1633
	if (!ast_strlen_zero(args.options) &&
1670
	if (!ast_strlen_zero(args.options) &&
1634
		ast_app_parse_options64(dial_exec_options, &opts, opt_args, args.options)) {
1671
		ast_app_parse_options64(dial_exec_options, &opts, opt_args, args.options)) {
1635
		pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
1672
		pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
1636
		goto done;
1673
		goto done;
1637
	}
1674
	}
1638

    
   
1675

   
1639
	if (ast_strlen_zero(args.peers)) {
1676
	if (ast_strlen_zero(args.peers)) {
1640
		ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
1677
		ast_log(LOG_WARNING, "Dial requires an argument (technology/number)\n");
1641
		pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
1678
		pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
1642
		goto done;
1679
		goto done;
1643
	}
1680
	}
1644

    
   
1681

   
1645
	if (ast_test_flag64(&opts, OPT_SCREEN_NOINTRO) && !ast_strlen_zero(opt_args[OPT_ARG_SCREEN_NOINTRO])) {
1682
	if (ast_test_flag64(&opts, OPT_SCREEN_NOINTRO) && !ast_strlen_zero(opt_args[OPT_ARG_SCREEN_NOINTRO])) {
1646
		delprivintro = atoi(opt_args[OPT_ARG_SCREEN_NOINTRO]);
1683
		delprivintro = atoi(opt_args[OPT_ARG_SCREEN_NOINTRO]);
1647

    
   
1684

   
1648
		if (delprivintro < 0 || delprivintro > 1) {
1685
		if (delprivintro < 0 || delprivintro > 1) {
1649
			ast_log(LOG_WARNING, "Unknown argument %d specified to n option, ignoring\n", delprivintro);
1686
			ast_log(LOG_WARNING, "Unknown argument %d specified to n option, ignoring\n", delprivintro);
1650
			delprivintro = 0;
1687
			delprivintro = 0;
1651
		}
1688
		}
1652
	}
1689
	}
1653

    
   
1690

   

    
   
1691
	if (!ast_test_flag64(&opts, OPT_RINGBACK)) {

    
   
1692
		opt_args[OPT_ARG_RINGBACK] = NULL;

    
   
1693
	}

    
   
1694

   
1654
	if (ast_test_flag64(&opts, OPT_OPERMODE)) {
1695
	if (ast_test_flag64(&opts, OPT_OPERMODE)) {
1655
		opermode = ast_strlen_zero(opt_args[OPT_ARG_OPERMODE]) ? 1 : atoi(opt_args[OPT_ARG_OPERMODE]);
1696
		opermode = ast_strlen_zero(opt_args[OPT_ARG_OPERMODE]) ? 1 : atoi(opt_args[OPT_ARG_OPERMODE]);
1656
		ast_verb(3, "Setting operator services mode to %d.\n", opermode);
1697
		ast_verb(3, "Setting operator services mode to %d.\n", opermode);
1657
	}
1698
	}
1658

    
   
1699

   
1659
	if (ast_test_flag64(&opts, OPT_DURATION_STOP) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_STOP])) {
1700
	if (ast_test_flag64(&opts, OPT_DURATION_STOP) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_STOP])) {
1660
		calldurationlimit.tv_sec = atoi(opt_args[OPT_ARG_DURATION_STOP]);
1701
		calldurationlimit.tv_sec = atoi(opt_args[OPT_ARG_DURATION_STOP]);
1661
		if (!calldurationlimit.tv_sec) {
1702
		if (!calldurationlimit.tv_sec) {
1662
			ast_log(LOG_WARNING, "Dial does not accept S(%s), hanging up.\n", opt_args[OPT_ARG_DURATION_STOP]);
1703
			ast_log(LOG_WARNING, "Dial does not accept S(%s), hanging up.\n", opt_args[OPT_ARG_DURATION_STOP]);
1663
			pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
1704
			pbx_builtin_setvar_helper(chan, "DIALSTATUS", pa.status);
1664
			goto done;
1705
			goto done;
1665
		}
1706
		}
1666
		ast_verb(3, "Setting call duration limit to %.3lf seconds.\n", calldurationlimit.tv_sec + calldurationlimit.tv_usec / 1000000.0);
1707
		ast_verb(3, "Setting call duration limit to %.3lf seconds.\n", calldurationlimit.tv_sec + calldurationlimit.tv_usec / 1000000.0);
1667
	}
1708
	}
1668

    
   
1709

   
1669
	if (ast_test_flag64(&opts, OPT_SENDDTMF) && !ast_strlen_zero(opt_args[OPT_ARG_SENDDTMF])) {
1710
	if (ast_test_flag64(&opts, OPT_SENDDTMF) && !ast_strlen_zero(opt_args[OPT_ARG_SENDDTMF])) {
1670
		dtmf_progress = opt_args[OPT_ARG_SENDDTMF];
1711
		dtmf_progress = opt_args[OPT_ARG_SENDDTMF];
1671
		dtmfcalled = strsep(&dtmf_progress, ":");
1712
		dtmfcalled = strsep(&dtmf_progress, ":");
1672
		dtmfcalling = strsep(&dtmf_progress, ":");
1713
		dtmfcalling = strsep(&dtmf_progress, ":");
1673
	}
1714
	}
1674

    
   
1715

   
1675
	if (ast_test_flag64(&opts, OPT_DURATION_LIMIT) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_LIMIT])) {
1716
	if (ast_test_flag64(&opts, OPT_DURATION_LIMIT) && !ast_strlen_zero(opt_args[OPT_ARG_DURATION_LIMIT])) {
1676
		if (ast_bridge_timelimit(chan, &config, opt_args[OPT_ARG_DURATION_LIMIT], &calldurationlimit))
1717
		if (ast_bridge_timelimit(chan, &config, opt_args[OPT_ARG_DURATION_LIMIT], &calldurationlimit))
1677
			goto done;
1718
			goto done;
1678
	}
1719
	}
1679

    
   
1720

   
1680
	if (ast_test_flag64(&opts, OPT_RESETCDR) && chan->cdr)
1721
	if (ast_test_flag64(&opts, OPT_RESETCDR) && chan->cdr)
1681
		ast_cdr_reset(chan->cdr, NULL);
1722
		ast_cdr_reset(chan->cdr, NULL);
1682
	if (ast_test_flag64(&opts, OPT_PRIVACY) && ast_strlen_zero(opt_args[OPT_ARG_PRIVACY]))
1723
	if (ast_test_flag64(&opts, OPT_PRIVACY) && ast_strlen_zero(opt_args[OPT_ARG_PRIVACY]))
1683
		opt_args[OPT_ARG_PRIVACY] = ast_strdupa(chan->exten);
1724
		opt_args[OPT_ARG_PRIVACY] = ast_strdupa(chan->exten);
1684

    
   
1725

   
1685
	if (ast_test_flag64(&opts, OPT_PRIVACY) || ast_test_flag64(&opts, OPT_SCREENING)) {
1726
	if (ast_test_flag64(&opts, OPT_PRIVACY) || ast_test_flag64(&opts, OPT_SCREENING)) {
1686
		res = setup_privacy_args(&pa, &opts, opt_args, chan);
1727
		res = setup_privacy_args(&pa, &opts, opt_args, chan);
1687
		if (res <= 0)
1728
		if (res <= 0)
1688
			goto out;
1729
			goto out;
1689
		res = -1; /* reset default */
1730
		res = -1; /* reset default */
1690
	}
1731
	}
1691

    
   
1732

   
1692
	if (ast_test_flag64(&opts, OPT_DTMF_EXIT) || ast_test_flag64(&opts, OPT_CALLER_HANGUP)) {
1733
	if (ast_test_flag64(&opts, OPT_DTMF_EXIT) || ast_test_flag64(&opts, OPT_CALLER_HANGUP)) {
1693
		__ast_answer(chan, 0, 0);
1734
		__ast_answer(chan, 0, 0);
1694
	}
1735
	}
1695

    
   
1736

   
1696
	if (continue_exec)
1737
	if (continue_exec)
1697
		*continue_exec = 0;
1738
		*continue_exec = 0;
1698

    
   
1739

   
1699
	/* If a channel group has been specified, get it for use when we create peer channels */
1740
	/* If a channel group has been specified, get it for use when we create peer channels */
1700

    
   
1741

   
1701
	ast_channel_lock(chan);
1742
	ast_channel_lock(chan);
1702
	if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP_ONCE"))) {
1743
	if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP_ONCE"))) {
1703
		outbound_group = ast_strdupa(outbound_group);	
1744
		outbound_group = ast_strdupa(outbound_group);	
1704
		pbx_builtin_setvar_helper(chan, "OUTBOUND_GROUP_ONCE", NULL);
1745
		pbx_builtin_setvar_helper(chan, "OUTBOUND_GROUP_ONCE", NULL);
1705
	} else if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP"))) {
1746
	} else if ((outbound_group = pbx_builtin_getvar_helper(chan, "OUTBOUND_GROUP"))) {
1706
		outbound_group = ast_strdupa(outbound_group);
1747
		outbound_group = ast_strdupa(outbound_group);
1707
	}
1748
	}
1708
	ast_channel_unlock(chan);	
1749
	ast_channel_unlock(chan);	
1709
	ast_copy_flags64(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID | OPT_CALLER_HANGUP | OPT_IGNORE_FORWARDING | OPT_IGNORE_CONNECTEDLINE |
1750
	ast_copy_flags64(peerflags, &opts, OPT_DTMF_EXIT | OPT_GO_ON | OPT_ORIGINAL_CLID | OPT_CALLER_HANGUP | OPT_IGNORE_FORWARDING | OPT_IGNORE_CONNECTEDLINE |
1710
			 OPT_CANCEL_TIMEOUT | OPT_ANNOUNCE | OPT_CALLEE_MACRO | OPT_CALLEE_GOSUB);
1751
			 OPT_CANCEL_TIMEOUT | OPT_ANNOUNCE | OPT_CALLEE_MACRO | OPT_CALLEE_GOSUB);
1711

    
   
1752

   
1712
	/* loop through the list of dial destinations */
1753
	/* loop through the list of dial destinations */
1713
	rest = args.peers;
1754
	rest = args.peers;
1714
	while ((cur = strsep(&rest, "&")) ) {
1755
	while ((cur = strsep(&rest, "&")) ) {
1715
		struct chanlist *tmp;
1756
		struct chanlist *tmp;
1716
		struct ast_channel *tc; /* channel for this destination */
1757
		struct ast_channel *tc; /* channel for this destination */
1717
		/* Get a technology/[device:]number pair */
1758
		/* Get a technology/[device:]number pair */
1718
		char *number = cur;
1759
		char *number = cur;
1719
		char *interface = ast_strdupa(number);
1760
		char *interface = ast_strdupa(number);
1720
		char *tech = strsep(&number, "/");
1761
		char *tech = strsep(&number, "/");
1721
		/* find if we already dialed this interface */
1762
		/* find if we already dialed this interface */
1722
		struct ast_dialed_interface *di;
1763
		struct ast_dialed_interface *di;
1723
		AST_LIST_HEAD(, ast_dialed_interface) *dialed_interfaces;
1764
		AST_LIST_HEAD(, ast_dialed_interface) *dialed_interfaces;
1724
		num_dialed++;
1765
		num_dialed++;
1725
		if (!number) {
1766
		if (!number) {
1726
			ast_log(LOG_WARNING, "Dial argument takes format (technology/[device:]number1)\n");
1767
			ast_log(LOG_WARNING, "Dial argument takes format (technology/[device:]number1)\n");
1727
			goto out;
1768
			goto out;
1728
		}
1769
		}
1729
		if (!(tmp = ast_calloc(1, sizeof(*tmp))))
1770
		if (!(tmp = ast_calloc(1, sizeof(*tmp))))
1730
			goto out;
1771
			goto out;
1731
		if (opts.flags) {
1772
		if (opts.flags) {
1732
			ast_copy_flags64(tmp, &opts,
1773
			ast_copy_flags64(tmp, &opts,
1733
				OPT_CANCEL_ELSEWHERE |
1774
				OPT_CANCEL_ELSEWHERE |
1734
				OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
1775
				OPT_CALLEE_TRANSFER | OPT_CALLER_TRANSFER |
1735
				OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
1776
				OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
1736
				OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
1777
				OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
1737
				OPT_CALLEE_PARK | OPT_CALLER_PARK |
1778
				OPT_CALLEE_PARK | OPT_CALLER_PARK |
1738
				OPT_CALLEE_MIXMONITOR | OPT_CALLER_MIXMONITOR |
1779
				OPT_CALLEE_MIXMONITOR | OPT_CALLER_MIXMONITOR |
1739
				OPT_RINGBACK | OPT_MUSICBACK | OPT_FORCECLID);
1780
				OPT_RINGBACK | OPT_MUSICBACK | OPT_FORCECLID);
1740
			ast_set2_flag64(tmp, args.url, DIAL_NOFORWARDHTML);
1781
			ast_set2_flag64(tmp, args.url, DIAL_NOFORWARDHTML);
1741
		}
1782
		}
1742
		ast_copy_string(numsubst, number, sizeof(numsubst));
1783
		ast_copy_string(numsubst, number, sizeof(numsubst));
1743
		/* Request the peer */
1784
		/* Request the peer */
1744

    
   
1785

   
1745
		ast_channel_lock(chan);
1786
		ast_channel_lock(chan);
1746
		datastore = ast_channel_datastore_find(chan, &dialed_interface_info, NULL);
1787
		datastore = ast_channel_datastore_find(chan, &dialed_interface_info, NULL);
1747
		/* If the incoming channel has previously had connected line information
1788
		/* If the incoming channel has previously had connected line information
1748
		 * set on it (perhaps through the CONNECTED_LINE dialplan function) then
1789
		 * set on it (perhaps through the CONNECTED_LINE dialplan function) then
1749
		 * seed the calllist's connected line information with this previously
1790
		 * seed the calllist's connected line information with this previously
1750
		 * acquired info
1791
		 * acquired info
1751
		 */
1792
		 */
1752
		if (chan->connected.id.number) {
1793
		if (chan->connected.id.number) {
1753
			ast_party_connected_line_copy(&tmp->connected, &chan->connected);
1794
			ast_party_connected_line_copy(&tmp->connected, &chan->connected);
1754
		}
1795
		}
1755
		ast_channel_unlock(chan);
1796
		ast_channel_unlock(chan);
1756

    
   
1797

   
1757
		if (datastore)
1798
		if (datastore)
1758
			dialed_interfaces = datastore->data;
1799
			dialed_interfaces = datastore->data;
1759
		else {
1800
		else {
1760
			if (!(datastore = ast_datastore_alloc(&dialed_interface_info, NULL))) {
1801
			if (!(datastore = ast_datastore_alloc(&dialed_interface_info, NULL))) {
1761
				ast_log(LOG_WARNING, "Unable to create channel datastore for dialed interfaces. Aborting!\n");
1802
				ast_log(LOG_WARNING, "Unable to create channel datastore for dialed interfaces. Aborting!\n");
1762
				chanlist_free(tmp);
1803
				chanlist_free(tmp);
1763
				goto out;
1804
				goto out;
1764
			}
1805
			}
1765

    
   
1806

   
1766
			datastore->inheritance = DATASTORE_INHERIT_FOREVER;
1807
			datastore->inheritance = DATASTORE_INHERIT_FOREVER;
1767

    
   
1808

   
1768
			if (!(dialed_interfaces = ast_calloc(1, sizeof(*dialed_interfaces)))) {
1809
			if (!(dialed_interfaces = ast_calloc(1, sizeof(*dialed_interfaces)))) {
1769
				ast_datastore_free(datastore);
1810
				ast_datastore_free(datastore);
1770
				chanlist_free(tmp);
1811
				chanlist_free(tmp);
1771
				goto out;
1812
				goto out;
1772
			}
1813
			}
1773

    
   
1814

   
1774
			datastore->data = dialed_interfaces;
1815
			datastore->data = dialed_interfaces;
1775
			AST_LIST_HEAD_INIT(dialed_interfaces);
1816
			AST_LIST_HEAD_INIT(dialed_interfaces);
1776

    
   
1817

   
1777
			ast_channel_lock(chan);
1818
			ast_channel_lock(chan);
1778
			ast_channel_datastore_add(chan, datastore);
1819
			ast_channel_datastore_add(chan, datastore);
1779
			ast_channel_unlock(chan);
1820
			ast_channel_unlock(chan);
1780
		}
1821
		}
1781

    
   
1822

   
1782
		AST_LIST_LOCK(dialed_interfaces);
1823
		AST_LIST_LOCK(dialed_interfaces);
1783
		AST_LIST_TRAVERSE(dialed_interfaces, di, list) {
1824
		AST_LIST_TRAVERSE(dialed_interfaces, di, list) {
1784
			if (!strcasecmp(di->interface, interface)) {
1825
			if (!strcasecmp(di->interface, interface)) {
1785
				ast_log(LOG_WARNING, "Skipping dialing interface '%s' again since it has already been dialed\n",
1826
				ast_log(LOG_WARNING, "Skipping dialing interface '%s' again since it has already been dialed\n",
1786
					di->interface);
1827
					di->interface);
1787
				break;
1828
				break;
1788
			}
1829
			}
1789
		}
1830
		}
1790
		AST_LIST_UNLOCK(dialed_interfaces);
1831
		AST_LIST_UNLOCK(dialed_interfaces);
1791

    
   
1832

   
1792
		if (di) {
1833
		if (di) {
1793
			fulldial++;
1834
			fulldial++;
1794
			chanlist_free(tmp);
1835
			chanlist_free(tmp);
1795
			continue;
1836
			continue;
1796
		}
1837
		}
1797

    
   
1838

   
1798
		/* It is always ok to dial a Local interface.  We only keep track of
1839
		/* It is always ok to dial a Local interface.  We only keep track of
1799
		 * which "real" interfaces have been dialed.  The Local channel will
1840
		 * which "real" interfaces have been dialed.  The Local channel will
1800
		 * inherit this list so that if it ends up dialing a real interface,
1841
		 * inherit this list so that if it ends up dialing a real interface,
1801
		 * it won't call one that has already been called. */
1842
		 * it won't call one that has already been called. */
1802
		if (strcasecmp(tech, "Local")) {
1843
		if (strcasecmp(tech, "Local")) {
1803
			if (!(di = ast_calloc(1, sizeof(*di) + strlen(interface)))) {
1844
			if (!(di = ast_calloc(1, sizeof(*di) + strlen(interface)))) {
1804
				AST_LIST_UNLOCK(dialed_interfaces);
1845
				AST_LIST_UNLOCK(dialed_interfaces);
1805
				chanlist_free(tmp);
1846
				chanlist_free(tmp);
1806
				goto out;
1847
				goto out;
1807
			}
1848
			}
1808
			strcpy(di->interface, interface);
1849
			strcpy(di->interface, interface);
1809

    
   
1850

   
1810
			AST_LIST_LOCK(dialed_interfaces);
1851
			AST_LIST_LOCK(dialed_interfaces);
1811
			AST_LIST_INSERT_TAIL(dialed_interfaces, di, list);
1852
			AST_LIST_INSERT_TAIL(dialed_interfaces, di, list);
1812
			AST_LIST_UNLOCK(dialed_interfaces);
1853
			AST_LIST_UNLOCK(dialed_interfaces);
1813
		}
1854
		}
1814

    
   
1855

   
1815
		tc = ast_request(tech, chan->nativeformats, chan, numsubst, &cause);
1856
		tc = ast_request(tech, chan->nativeformats, chan, numsubst, &cause);
1816
		if (!tc) {
1857
		if (!tc) {
1817
			/* If we can't, just go on to the next call */
1858
			/* If we can't, just go on to the next call */
1818
			ast_log(LOG_WARNING, "Unable to create channel of type '%s' (cause %d - %s)\n",
1859
			ast_log(LOG_WARNING, "Unable to create channel of type '%s' (cause %d - %s)\n",
1819
				tech, cause, ast_cause2str(cause));
1860
				tech, cause, ast_cause2str(cause));
1820
			handle_cause(cause, &num);
1861
			handle_cause(cause, &num);
1821
			if (!rest) /* we are on the last destination */
1862
			if (!rest) /* we are on the last destination */
1822
				chan->hangupcause = cause;
1863
				chan->hangupcause = cause;
1823
			chanlist_free(tmp);
1864
			chanlist_free(tmp);
1824
			continue;
1865
			continue;
1825
		}
1866
		}
1826
		pbx_builtin_setvar_helper(tc, "DIALEDPEERNUMBER", numsubst);
1867
		pbx_builtin_setvar_helper(tc, "DIALEDPEERNUMBER", numsubst);
1827

    
   
1868

   
1828
		ast_channel_lock(tc);
1869
		ast_channel_lock(tc);
1829
		while (ast_channel_trylock(chan)) {
1870
		while (ast_channel_trylock(chan)) {
1830
			CHANNEL_DEADLOCK_AVOIDANCE(tc);
1871
			CHANNEL_DEADLOCK_AVOIDANCE(tc);
1831
		}
1872
		}
1832
		/* Setup outgoing SDP to match incoming one */
1873
		/* Setup outgoing SDP to match incoming one */
1833
		if (!outgoing && !rest && CAN_EARLY_BRIDGE(peerflags, chan, tc)) {
1874
		if (!outgoing && !rest && CAN_EARLY_BRIDGE(peerflags, chan, tc)) {
1834
			ast_rtp_instance_early_bridge_make_compatible(tc, chan);
1875
			ast_rtp_instance_early_bridge_make_compatible(tc, chan);
1835
		}
1876
		}
1836
		
1877
		
1837
		/* Inherit specially named variables from parent channel */
1878
		/* Inherit specially named variables from parent channel */
1838
		ast_channel_inherit_variables(chan, tc);
1879
		ast_channel_inherit_variables(chan, tc);
1839
		ast_channel_datastore_inherit(chan, tc);
1880
		ast_channel_datastore_inherit(chan, tc);
1840

    
   
1881

   
1841
		tc->appl = "AppDial";
1882
		tc->appl = "AppDial";
1842
		tc->data = "(Outgoing Line)";
1883
		tc->data = "(Outgoing Line)";
1843
		memset(&tc->whentohangup, 0, sizeof(tc->