Review Board 1.7.16


sync chan_dahdi->p->outgoing with sig_XXX->p-outgoing

Review Request #1747 - Created Feb. 15, 2012 and submitted

Alec Davis
1.8 and above
Reviewers
asterisk-dev
Asterisk
Jeremy Pepper review https://reviewboard.asterisk.org/r/1737/ highlighted an issue where p->outgoing flag isn't in sync between chan_dahdi and sig_analog
sig_analog: Basic calls in and out with analog TDM800P
sig_pri and sig_ss7: compiles

Diff revision 3

This is not the most recent revision of the diff. The latest diff is revision 5. See what's changed.

1 2 3 4 5
1 2 3 4 5

  1. trunk/channels/chan_dahdi.c: Loading...
  2. trunk/channels/sig_analog.h: Loading...
  3. trunk/channels/sig_analog.c: Loading...
trunk/channels/chan_dahdi.c
Revision 353434 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 DAHDI for Pseudo TDM
21
 * \brief DAHDI for Pseudo TDM
22
 *
22
 *
23
 * \author Mark Spencer <markster@digium.com>
23
 * \author Mark Spencer <markster@digium.com>
24
 *
24
 *
25
 * Connects to the DAHDI telephony library as well as
25
 * Connects to the DAHDI telephony library as well as
26
 * libpri. Libpri is optional and needed only if you are
26
 * libpri. Libpri is optional and needed only if you are
27
 * going to use ISDN connections.
27
 * going to use ISDN connections.
28
 *
28
 *
29
 * You need to install libraries before you attempt to compile
29
 * You need to install libraries before you attempt to compile
30
 * and install the DAHDI channel.
30
 * and install the DAHDI channel.
31
 *
31
 *
32
 * \par See also
32
 * \par See also
33
 * \arg \ref Config_dahdi
33
 * \arg \ref Config_dahdi
34
 *
34
 *
35
 * \ingroup channel_drivers
35
 * \ingroup channel_drivers
36
 *
36
 *
37
 * \todo Deprecate the "musiconhold" configuration option post 1.4
37
 * \todo Deprecate the "musiconhold" configuration option post 1.4
38
 */
38
 */
39

    
   
39

   
40
/*** MODULEINFO
40
/*** MODULEINFO
41
	<use type="module">res_smdi</use>
41
	<use type="module">res_smdi</use>
42
	<depend>dahdi</depend>
42
	<depend>dahdi</depend>
43
	<depend>tonezone</depend>
43
	<depend>tonezone</depend>
44
	<use type="external">pri</use>
44
	<use type="external">pri</use>
45
	<use type="external">ss7</use>
45
	<use type="external">ss7</use>
46
	<use type="external">openr2</use>
46
	<use type="external">openr2</use>
47
	<support_level>core</support_level>
47
	<support_level>core</support_level>
48
 ***/
48
 ***/
49

    
   
49

   
50
#include "asterisk.h"
50
#include "asterisk.h"
51

    
   
51

   
52
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
52
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
53

    
   
53

   
54
#if defined(__NetBSD__) || defined(__FreeBSD__)
54
#if defined(__NetBSD__) || defined(__FreeBSD__)
55
#include <pthread.h>
55
#include <pthread.h>
56
#include <signal.h>
56
#include <signal.h>
57
#else
57
#else
58
#include <sys/signal.h>
58
#include <sys/signal.h>
59
#endif
59
#endif
60
#include <sys/ioctl.h>
60
#include <sys/ioctl.h>
61
#include <sys/stat.h>
61
#include <sys/stat.h>
62
#include <math.h>
62
#include <math.h>
63
#include <ctype.h>
63
#include <ctype.h>
64

    
   
64

   
65
#include <dahdi/user.h>
65
#include <dahdi/user.h>
66
#include <dahdi/tonezone.h>
66
#include <dahdi/tonezone.h>
67
#include "sig_analog.h"
67
#include "sig_analog.h"
68
/* Analog signaling is currently still present in chan_dahdi for use with
68
/* Analog signaling is currently still present in chan_dahdi for use with
69
 * radio. Sig_analog does not currently handle any radio operations. If
69
 * radio. Sig_analog does not currently handle any radio operations. If
70
 * radio only uses analog signaling, then the radio handling logic could
70
 * radio only uses analog signaling, then the radio handling logic could
71
 * be placed in sig_analog and the duplicated code could be removed.
71
 * be placed in sig_analog and the duplicated code could be removed.
72
 */
72
 */
73

    
   
73

   
74
#ifdef HAVE_PRI
74
#ifdef HAVE_PRI
75
#include "sig_pri.h"
75
#include "sig_pri.h"
76
#endif
76
#endif
77

    
   
77

   
78
#if defined(HAVE_SS7)
78
#if defined(HAVE_SS7)
79
#include "sig_ss7.h"
79
#include "sig_ss7.h"
80
#endif	/* defined(HAVE_SS7) */
80
#endif	/* defined(HAVE_SS7) */
81

    
   
81

   
82
#ifdef HAVE_OPENR2
82
#ifdef HAVE_OPENR2
83
/* put this here until sig_mfcr2 comes along */
83
/* put this here until sig_mfcr2 comes along */
84
#define SIG_MFCR2_MAX_CHANNELS	672		/*!< No more than a DS3 per trunk group */
84
#define SIG_MFCR2_MAX_CHANNELS	672		/*!< No more than a DS3 per trunk group */
85
#include <openr2.h>
85
#include <openr2.h>
86
#endif
86
#endif
87

    
   
87

   
88
#include "asterisk/lock.h"
88
#include "asterisk/lock.h"
89
#include "asterisk/channel.h"
89
#include "asterisk/channel.h"
90
#include "asterisk/config.h"
90
#include "asterisk/config.h"
91
#include "asterisk/module.h"
91
#include "asterisk/module.h"
92
#include "asterisk/pbx.h"
92
#include "asterisk/pbx.h"
93
#include "asterisk/file.h"
93
#include "asterisk/file.h"
94
#include "asterisk/ulaw.h"
94
#include "asterisk/ulaw.h"
95
#include "asterisk/alaw.h"
95
#include "asterisk/alaw.h"
96
#include "asterisk/callerid.h"
96
#include "asterisk/callerid.h"
97
#include "asterisk/adsi.h"
97
#include "asterisk/adsi.h"
98
#include "asterisk/cli.h"
98
#include "asterisk/cli.h"
99
#include "asterisk/cdr.h"
99
#include "asterisk/cdr.h"
100
#include "asterisk/cel.h"
100
#include "asterisk/cel.h"
101
#include "asterisk/features.h"
101
#include "asterisk/features.h"
102
#include "asterisk/musiconhold.h"
102
#include "asterisk/musiconhold.h"
103
#include "asterisk/say.h"
103
#include "asterisk/say.h"
104
#include "asterisk/tdd.h"
104
#include "asterisk/tdd.h"
105
#include "asterisk/app.h"
105
#include "asterisk/app.h"
106
#include "asterisk/dsp.h"
106
#include "asterisk/dsp.h"
107
#include "asterisk/astdb.h"
107
#include "asterisk/astdb.h"
108
#include "asterisk/manager.h"
108
#include "asterisk/manager.h"
109
#include "asterisk/causes.h"
109
#include "asterisk/causes.h"
110
#include "asterisk/term.h"
110
#include "asterisk/term.h"
111
#include "asterisk/utils.h"
111
#include "asterisk/utils.h"
112
#include "asterisk/transcap.h"
112
#include "asterisk/transcap.h"
113
#include "asterisk/stringfields.h"
113
#include "asterisk/stringfields.h"
114
#include "asterisk/abstract_jb.h"
114
#include "asterisk/abstract_jb.h"
115
#include "asterisk/smdi.h"
115
#include "asterisk/smdi.h"
116
#include "asterisk/astobj.h"
116
#include "asterisk/astobj.h"
117
#include "asterisk/event.h"
117
#include "asterisk/event.h"
118
#include "asterisk/devicestate.h"
118
#include "asterisk/devicestate.h"
119
#include "asterisk/paths.h"
119
#include "asterisk/paths.h"
120
#include "asterisk/ccss.h"
120
#include "asterisk/ccss.h"
121
#include "asterisk/data.h"
121
#include "asterisk/data.h"
122

    
   
122

   
123
/*** DOCUMENTATION
123
/*** DOCUMENTATION
124
	<application name="DAHDISendKeypadFacility" language="en_US">
124
	<application name="DAHDISendKeypadFacility" language="en_US">
125
		<synopsis>
125
		<synopsis>
126
			Send digits out of band over a PRI.
126
			Send digits out of band over a PRI.
127
		</synopsis>
127
		</synopsis>
128
		<syntax>
128
		<syntax>
129
			<parameter name="digits" required="true" />
129
			<parameter name="digits" required="true" />
130
		</syntax>
130
		</syntax>
131
		<description>
131
		<description>
132
			<para>This application will send the given string of digits in a Keypad
132
			<para>This application will send the given string of digits in a Keypad
133
			Facility IE over the current channel.</para>
133
			Facility IE over the current channel.</para>
134
		</description>
134
		</description>
135
	</application>
135
	</application>
136
	<application name="DAHDISendCallreroutingFacility" language="en_US">
136
	<application name="DAHDISendCallreroutingFacility" language="en_US">
137
		<synopsis>
137
		<synopsis>
138
			Send an ISDN call rerouting/deflection facility message.
138
			Send an ISDN call rerouting/deflection facility message.
139
		</synopsis>
139
		</synopsis>
140
		<syntax argsep=",">
140
		<syntax argsep=",">
141
			<parameter name="destination" required="true">
141
			<parameter name="destination" required="true">
142
				<para>Destination number.</para>
142
				<para>Destination number.</para>
143
			</parameter>
143
			</parameter>
144
			<parameter name="original">
144
			<parameter name="original">
145
				<para>Original called number.</para>
145
				<para>Original called number.</para>
146
			</parameter>
146
			</parameter>
147
			<parameter name="reason">
147
			<parameter name="reason">
148
				<para>Diversion reason, if not specified defaults to <literal>unknown</literal></para>
148
				<para>Diversion reason, if not specified defaults to <literal>unknown</literal></para>
149
			</parameter>
149
			</parameter>
150
		</syntax>
150
		</syntax>
151
		<description>
151
		<description>
152
			<para>This application will send an ISDN switch specific call
152
			<para>This application will send an ISDN switch specific call
153
			rerouting/deflection facility message over the current channel.
153
			rerouting/deflection facility message over the current channel.
154
			Supported switches depend upon the version of libpri in use.</para>
154
			Supported switches depend upon the version of libpri in use.</para>
155
		</description>
155
		</description>
156
	</application>
156
	</application>
157
	<application name="DAHDIAcceptR2Call" language="en_US">
157
	<application name="DAHDIAcceptR2Call" language="en_US">
158
		<synopsis>
158
		<synopsis>
159
			Accept an R2 call if its not already accepted (you still need to answer it)
159
			Accept an R2 call if its not already accepted (you still need to answer it)
160
		</synopsis>
160
		</synopsis>
161
		<syntax>
161
		<syntax>
162
			<parameter name="charge" required="true">
162
			<parameter name="charge" required="true">
163
				<para>Yes or No.</para>
163
				<para>Yes or No.</para>
164
				<para>Whether you want to accept the call with charge or without charge.</para>
164
				<para>Whether you want to accept the call with charge or without charge.</para>
165
			</parameter>
165
			</parameter>
166
		</syntax>
166
		</syntax>
167
		<description>
167
		<description>
168
			<para>This application will Accept the R2 call either with charge or no charge.</para>
168
			<para>This application will Accept the R2 call either with charge or no charge.</para>
169
		</description>
169
		</description>
170
	</application>
170
	</application>
171
	<manager name="DAHDITransfer" language="en_US">
171
	<manager name="DAHDITransfer" language="en_US">
172
		<synopsis>
172
		<synopsis>
173
			Transfer DAHDI Channel.
173
			Transfer DAHDI Channel.
174
		</synopsis>
174
		</synopsis>
175
		<syntax>
175
		<syntax>
176
			<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
176
			<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
177
			<parameter name="DAHDIChannel" required="true">
177
			<parameter name="DAHDIChannel" required="true">
178
				<para>DAHDI channel number to transfer.</para>
178
				<para>DAHDI channel number to transfer.</para>
179
			</parameter>
179
			</parameter>
180
		</syntax>
180
		</syntax>
181
		<description>
181
		<description>
182
			<para>Simulate a flash hook event by the user connected to the channel.</para>
182
			<para>Simulate a flash hook event by the user connected to the channel.</para>
183
			<note><para>Valid only for analog channels.</para></note>
183
			<note><para>Valid only for analog channels.</para></note>
184
		</description>
184
		</description>
185
	</manager>
185
	</manager>
186
	<manager name="DAHDIHangup" language="en_US">
186
	<manager name="DAHDIHangup" language="en_US">
187
		<synopsis>
187
		<synopsis>
188
			Hangup DAHDI Channel.
188
			Hangup DAHDI Channel.
189
		</synopsis>
189
		</synopsis>
190
		<syntax>
190
		<syntax>
191
			<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
191
			<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
192
			<parameter name="DAHDIChannel" required="true">
192
			<parameter name="DAHDIChannel" required="true">
193
				<para>DAHDI channel number to hangup.</para>
193
				<para>DAHDI channel number to hangup.</para>
194
			</parameter>
194
			</parameter>
195
		</syntax>
195
		</syntax>
196
		<description>
196
		<description>
197
			<para>Simulate an on-hook event by the user connected to the channel.</para>
197
			<para>Simulate an on-hook event by the user connected to the channel.</para>
198
			<note><para>Valid only for analog channels.</para></note>
198
			<note><para>Valid only for analog channels.</para></note>
199
		</description>
199
		</description>
200
	</manager>
200
	</manager>
201
	<manager name="DAHDIDialOffhook" language="en_US">
201
	<manager name="DAHDIDialOffhook" language="en_US">
202
		<synopsis>
202
		<synopsis>
203
			Dial over DAHDI channel while offhook.
203
			Dial over DAHDI channel while offhook.
204
		</synopsis>
204
		</synopsis>
205
		<syntax>
205
		<syntax>
206
			<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
206
			<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
207
			<parameter name="DAHDIChannel" required="true">
207
			<parameter name="DAHDIChannel" required="true">
208
				<para>DAHDI channel number to dial digits.</para>
208
				<para>DAHDI channel number to dial digits.</para>
209
			</parameter>
209
			</parameter>
210
			<parameter name="Number" required="true">
210
			<parameter name="Number" required="true">
211
				<para>Digits to dial.</para>
211
				<para>Digits to dial.</para>
212
			</parameter>
212
			</parameter>
213
		</syntax>
213
		</syntax>
214
		<description>
214
		<description>
215
			<para>Generate DTMF control frames to the bridged peer.</para>
215
			<para>Generate DTMF control frames to the bridged peer.</para>
216
		</description>
216
		</description>
217
	</manager>
217
	</manager>
218
	<manager name="DAHDIDNDon" language="en_US">
218
	<manager name="DAHDIDNDon" language="en_US">
219
		<synopsis>
219
		<synopsis>
220
			Toggle DAHDI channel Do Not Disturb status ON.
220
			Toggle DAHDI channel Do Not Disturb status ON.
221
		</synopsis>
221
		</synopsis>
222
		<syntax>
222
		<syntax>
223
			<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
223
			<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
224
			<parameter name="DAHDIChannel" required="true">
224
			<parameter name="DAHDIChannel" required="true">
225
				<para>DAHDI channel number to set DND on.</para>
225
				<para>DAHDI channel number to set DND on.</para>
226
			</parameter>
226
			</parameter>
227
		</syntax>
227
		</syntax>
228
		<description>
228
		<description>
229
			<para>Equivalent to the CLI command "dahdi set dnd <variable>channel</variable> on".</para>
229
			<para>Equivalent to the CLI command "dahdi set dnd <variable>channel</variable> on".</para>
230
			<note><para>Feature only supported by analog channels.</para></note>
230
			<note><para>Feature only supported by analog channels.</para></note>
231
		</description>
231
		</description>
232
	</manager>
232
	</manager>
233
	<manager name="DAHDIDNDoff" language="en_US">
233
	<manager name="DAHDIDNDoff" language="en_US">
234
		<synopsis>
234
		<synopsis>
235
			Toggle DAHDI channel Do Not Disturb status OFF.
235
			Toggle DAHDI channel Do Not Disturb status OFF.
236
		</synopsis>
236
		</synopsis>
237
		<syntax>
237
		<syntax>
238
			<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
238
			<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
239
			<parameter name="DAHDIChannel" required="true">
239
			<parameter name="DAHDIChannel" required="true">
240
				<para>DAHDI channel number to set DND off.</para>
240
				<para>DAHDI channel number to set DND off.</para>
241
			</parameter>
241
			</parameter>
242
		</syntax>
242
		</syntax>
243
		<description>
243
		<description>
244
			<para>Equivalent to the CLI command "dahdi set dnd <variable>channel</variable> off".</para>
244
			<para>Equivalent to the CLI command "dahdi set dnd <variable>channel</variable> off".</para>
245
			<note><para>Feature only supported by analog channels.</para></note>
245
			<note><para>Feature only supported by analog channels.</para></note>
246
		</description>
246
		</description>
247
	</manager>
247
	</manager>
248
	<manager name="DAHDIShowChannels" language="en_US">
248
	<manager name="DAHDIShowChannels" language="en_US">
249
		<synopsis>
249
		<synopsis>
250
			Show status of DAHDI channels.
250
			Show status of DAHDI channels.
251
		</synopsis>
251
		</synopsis>
252
		<syntax>
252
		<syntax>
253
			<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
253
			<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
254
			<parameter name="DAHDIChannel">
254
			<parameter name="DAHDIChannel">
255
				<para>Specify the specific channel number to show.  Show all channels if zero or not present.</para>
255
				<para>Specify the specific channel number to show.  Show all channels if zero or not present.</para>
256
			</parameter>
256
			</parameter>
257
		</syntax>
257
		</syntax>
258
		<description>
258
		<description>
259
			<para>Similar to the CLI command "dahdi show channels".</para>
259
			<para>Similar to the CLI command "dahdi show channels".</para>
260
		</description>
260
		</description>
261
	</manager>
261
	</manager>
262
	<manager name="DAHDIRestart" language="en_US">
262
	<manager name="DAHDIRestart" language="en_US">
263
		<synopsis>
263
		<synopsis>
264
			Fully Restart DAHDI channels (terminates calls).
264
			Fully Restart DAHDI channels (terminates calls).
265
		</synopsis>
265
		</synopsis>
266
		<syntax>
266
		<syntax>
267
			<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
267
			<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
268
		</syntax>
268
		</syntax>
269
		<description>
269
		<description>
270
			<para>Equivalent to the CLI command "dahdi restart".</para>
270
			<para>Equivalent to the CLI command "dahdi restart".</para>
271
		</description>
271
		</description>
272
	</manager>
272
	</manager>
273
	<manager name="PRIShowSpans" language="en_US">
273
	<manager name="PRIShowSpans" language="en_US">
274
		<synopsis>
274
		<synopsis>
275
			Show status of PRI spans.
275
			Show status of PRI spans.
276
		</synopsis>
276
		</synopsis>
277
		<syntax>
277
		<syntax>
278
			<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
278
			<xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
279
			<parameter name="Span">
279
			<parameter name="Span">
280
				<para>Specify the specific span to show.  Show all spans if zero or not present.</para>
280
				<para>Specify the specific span to show.  Show all spans if zero or not present.</para>
281
			</parameter>
281
			</parameter>
282
		</syntax>
282
		</syntax>
283
		<description>
283
		<description>
284
			<para>Similar to the CLI command "pri show spans".</para>
284
			<para>Similar to the CLI command "pri show spans".</para>
285
		</description>
285
		</description>
286
	</manager>
286
	</manager>
287
 ***/
287
 ***/
288

    
   
288

   
289
#define SMDI_MD_WAIT_TIMEOUT 1500 /* 1.5 seconds */
289
#define SMDI_MD_WAIT_TIMEOUT 1500 /* 1.5 seconds */
290

    
   
290

   
291
static const char * const lbostr[] = {
291
static const char * const lbostr[] = {
292
"0 db (CSU)/0-133 feet (DSX-1)",
292
"0 db (CSU)/0-133 feet (DSX-1)",
293
"133-266 feet (DSX-1)",
293
"133-266 feet (DSX-1)",
294
"266-399 feet (DSX-1)",
294
"266-399 feet (DSX-1)",
295
"399-533 feet (DSX-1)",
295
"399-533 feet (DSX-1)",
296
"533-655 feet (DSX-1)",
296
"533-655 feet (DSX-1)",
297
"-7.5db (CSU)",
297
"-7.5db (CSU)",
298
"-15db (CSU)",
298
"-15db (CSU)",
299
"-22.5db (CSU)"
299
"-22.5db (CSU)"
300
};
300
};
301

    
   
301

   
302
/*! Global jitterbuffer configuration - by default, jb is disabled
302
/*! Global jitterbuffer configuration - by default, jb is disabled
303
 *  \note Values shown here match the defaults shown in chan_dahdi.conf.sample */
303
 *  \note Values shown here match the defaults shown in chan_dahdi.conf.sample */
304
static struct ast_jb_conf default_jbconf =
304
static struct ast_jb_conf default_jbconf =
305
{
305
{
306
	.flags = 0,
306
	.flags = 0,
307
	.max_size = 200,
307
	.max_size = 200,
308
	.resync_threshold = 1000,
308
	.resync_threshold = 1000,
309
	.impl = "fixed",
309
	.impl = "fixed",
310
	.target_extra = 40,
310
	.target_extra = 40,
311
};
311
};
312
static struct ast_jb_conf global_jbconf;
312
static struct ast_jb_conf global_jbconf;
313

    
   
313

   
314
/*!
314
/*!
315
 * \note Define ZHONE_HACK to cause us to go off hook and then back on hook when
315
 * \note Define ZHONE_HACK to cause us to go off hook and then back on hook when
316
 * the user hangs up to reset the state machine so ring works properly.
316
 * the user hangs up to reset the state machine so ring works properly.
317
 * This is used to be able to support kewlstart by putting the zhone in
317
 * This is used to be able to support kewlstart by putting the zhone in
318
 * groundstart mode since their forward disconnect supervision is entirely
318
 * groundstart mode since their forward disconnect supervision is entirely
319
 * broken even though their documentation says it isn't and their support
319
 * broken even though their documentation says it isn't and their support
320
 * is entirely unwilling to provide any assistance with their channel banks
320
 * is entirely unwilling to provide any assistance with their channel banks
321
 * even though their web site says they support their products for life.
321
 * even though their web site says they support their products for life.
322
 */
322
 */
323
/* #define ZHONE_HACK */
323
/* #define ZHONE_HACK */
324

    
   
324

   
325
/*! \brief Typically, how many rings before we should send Caller*ID */
325
/*! \brief Typically, how many rings before we should send Caller*ID */
326
#define DEFAULT_CIDRINGS 1
326
#define DEFAULT_CIDRINGS 1
327

    
   
327

   
328
#define AST_LAW(p) (((p)->law == DAHDI_LAW_ALAW) ? AST_FORMAT_ALAW : AST_FORMAT_ULAW)
328
#define AST_LAW(p) (((p)->law == DAHDI_LAW_ALAW) ? AST_FORMAT_ALAW : AST_FORMAT_ULAW)
329

    
   
329

   
330

    
   
330

   
331
/*! \brief Signaling types that need to use MF detection should be placed in this macro */
331
/*! \brief Signaling types that need to use MF detection should be placed in this macro */
332
#define NEED_MFDETECT(p) (((p)->sig == SIG_FEATDMF) || ((p)->sig == SIG_FEATDMF_TA) || ((p)->sig == SIG_E911) || ((p)->sig == SIG_FGC_CAMA) || ((p)->sig == SIG_FGC_CAMAMF) || ((p)->sig == SIG_FEATB))
332
#define NEED_MFDETECT(p) (((p)->sig == SIG_FEATDMF) || ((p)->sig == SIG_FEATDMF_TA) || ((p)->sig == SIG_E911) || ((p)->sig == SIG_FGC_CAMA) || ((p)->sig == SIG_FGC_CAMAMF) || ((p)->sig == SIG_FEATB))
333

    
   
333

   
334
static const char tdesc[] = "DAHDI Telephony Driver"
334
static const char tdesc[] = "DAHDI Telephony Driver"
335
#if defined(HAVE_PRI) || defined(HAVE_SS7) || defined(HAVE_OPENR2)
335
#if defined(HAVE_PRI) || defined(HAVE_SS7) || defined(HAVE_OPENR2)
336
	" w/"
336
	" w/"
337
	#if defined(HAVE_PRI)
337
	#if defined(HAVE_PRI)
338
		"PRI"
338
		"PRI"
339
	#endif	/* defined(HAVE_PRI) */
339
	#endif	/* defined(HAVE_PRI) */
340
	#if defined(HAVE_SS7)
340
	#if defined(HAVE_SS7)
341
		#if defined(HAVE_PRI)
341
		#if defined(HAVE_PRI)
342
		" & "
342
		" & "
343
		#endif	/* defined(HAVE_PRI) */
343
		#endif	/* defined(HAVE_PRI) */
344
		"SS7"
344
		"SS7"
345
	#endif	/* defined(HAVE_SS7) */
345
	#endif	/* defined(HAVE_SS7) */
346
	#if defined(HAVE_OPENR2)
346
	#if defined(HAVE_OPENR2)
347
		#if defined(HAVE_PRI) || defined(HAVE_SS7)
347
		#if defined(HAVE_PRI) || defined(HAVE_SS7)
348
		" & "
348
		" & "
349
		#endif	/* defined(HAVE_PRI) || defined(HAVE_SS7) */
349
		#endif	/* defined(HAVE_PRI) || defined(HAVE_SS7) */
350
		"MFC/R2"
350
		"MFC/R2"
351
	#endif	/* defined(HAVE_OPENR2) */
351
	#endif	/* defined(HAVE_OPENR2) */
352
#endif	/* defined(HAVE_PRI) || defined(HAVE_SS7) || defined(HAVE_OPENR2) */
352
#endif	/* defined(HAVE_PRI) || defined(HAVE_SS7) || defined(HAVE_OPENR2) */
353
;
353
;
354

    
   
354

   
355
static const char config[] = "chan_dahdi.conf";
355
static const char config[] = "chan_dahdi.conf";
356

    
   
356

   
357
#define SIG_EM		DAHDI_SIG_EM
357
#define SIG_EM		DAHDI_SIG_EM
358
#define SIG_EMWINK 	(0x0100000 | DAHDI_SIG_EM)
358
#define SIG_EMWINK 	(0x0100000 | DAHDI_SIG_EM)
359
#define SIG_FEATD	(0x0200000 | DAHDI_SIG_EM)
359
#define SIG_FEATD	(0x0200000 | DAHDI_SIG_EM)
360
#define	SIG_FEATDMF	(0x0400000 | DAHDI_SIG_EM)
360
#define	SIG_FEATDMF	(0x0400000 | DAHDI_SIG_EM)
361
#define	SIG_FEATB	(0x0800000 | DAHDI_SIG_EM)
361
#define	SIG_FEATB	(0x0800000 | DAHDI_SIG_EM)
362
#define	SIG_E911	(0x1000000 | DAHDI_SIG_EM)
362
#define	SIG_E911	(0x1000000 | DAHDI_SIG_EM)
363
#define	SIG_FEATDMF_TA	(0x2000000 | DAHDI_SIG_EM)
363
#define	SIG_FEATDMF_TA	(0x2000000 | DAHDI_SIG_EM)
364
#define	SIG_FGC_CAMA	(0x4000000 | DAHDI_SIG_EM)
364
#define	SIG_FGC_CAMA	(0x4000000 | DAHDI_SIG_EM)
365
#define	SIG_FGC_CAMAMF	(0x8000000 | DAHDI_SIG_EM)
365
#define	SIG_FGC_CAMAMF	(0x8000000 | DAHDI_SIG_EM)
366
#define SIG_FXSLS	DAHDI_SIG_FXSLS
366
#define SIG_FXSLS	DAHDI_SIG_FXSLS
367
#define SIG_FXSGS	DAHDI_SIG_FXSGS
367
#define SIG_FXSGS	DAHDI_SIG_FXSGS
368
#define SIG_FXSKS	DAHDI_SIG_FXSKS
368
#define SIG_FXSKS	DAHDI_SIG_FXSKS
369
#define SIG_FXOLS	DAHDI_SIG_FXOLS
369
#define SIG_FXOLS	DAHDI_SIG_FXOLS
370
#define SIG_FXOGS	DAHDI_SIG_FXOGS
370
#define SIG_FXOGS	DAHDI_SIG_FXOGS
371
#define SIG_FXOKS	DAHDI_SIG_FXOKS
371
#define SIG_FXOKS	DAHDI_SIG_FXOKS
372
#define SIG_PRI		DAHDI_SIG_CLEAR
372
#define SIG_PRI		DAHDI_SIG_CLEAR
373
#define SIG_BRI		(0x2000000 | DAHDI_SIG_CLEAR)
373
#define SIG_BRI		(0x2000000 | DAHDI_SIG_CLEAR)
374
#define SIG_BRI_PTMP	(0X4000000 | DAHDI_SIG_CLEAR)
374
#define SIG_BRI_PTMP	(0X4000000 | DAHDI_SIG_CLEAR)
375
#define SIG_SS7		(0x1000000 | DAHDI_SIG_CLEAR)
375
#define SIG_SS7		(0x1000000 | DAHDI_SIG_CLEAR)
376
#define SIG_MFCR2 	DAHDI_SIG_CAS
376
#define SIG_MFCR2 	DAHDI_SIG_CAS
377
#define	SIG_SF		DAHDI_SIG_SF
377
#define	SIG_SF		DAHDI_SIG_SF
378
#define SIG_SFWINK 	(0x0100000 | DAHDI_SIG_SF)
378
#define SIG_SFWINK 	(0x0100000 | DAHDI_SIG_SF)
379
#define SIG_SF_FEATD	(0x0200000 | DAHDI_SIG_SF)
379
#define SIG_SF_FEATD	(0x0200000 | DAHDI_SIG_SF)
380
#define	SIG_SF_FEATDMF	(0x0400000 | DAHDI_SIG_SF)
380
#define	SIG_SF_FEATDMF	(0x0400000 | DAHDI_SIG_SF)
381
#define	SIG_SF_FEATB	(0x0800000 | DAHDI_SIG_SF)
381
#define	SIG_SF_FEATB	(0x0800000 | DAHDI_SIG_SF)
382
#define SIG_EM_E1	DAHDI_SIG_EM_E1
382
#define SIG_EM_E1	DAHDI_SIG_EM_E1
383

    
   
383

   
384
#ifdef LOTS_OF_SPANS
384
#ifdef LOTS_OF_SPANS
385
#define NUM_SPANS	DAHDI_MAX_SPANS
385
#define NUM_SPANS	DAHDI_MAX_SPANS
386
#else
386
#else
387
#define NUM_SPANS 		32
387
#define NUM_SPANS 		32
388
#endif
388
#endif
389

    
   
389

   
390
#define CHAN_PSEUDO	-2
390
#define CHAN_PSEUDO	-2
391

    
   
391

   
392
#define CALLPROGRESS_PROGRESS		1
392
#define CALLPROGRESS_PROGRESS		1
393
#define CALLPROGRESS_FAX_OUTGOING	2
393
#define CALLPROGRESS_FAX_OUTGOING	2
394
#define CALLPROGRESS_FAX_INCOMING	4
394
#define CALLPROGRESS_FAX_INCOMING	4
395
#define CALLPROGRESS_FAX		(CALLPROGRESS_FAX_INCOMING | CALLPROGRESS_FAX_OUTGOING)
395
#define CALLPROGRESS_FAX		(CALLPROGRESS_FAX_INCOMING | CALLPROGRESS_FAX_OUTGOING)
396

    
   
396

   
397
#define NUM_CADENCE_MAX 25
397
#define NUM_CADENCE_MAX 25
398
static int num_cadence = 4;
398
static int num_cadence = 4;
399
static int user_has_defined_cadences = 0;
399
static int user_has_defined_cadences = 0;
400

    
   
400

   
401
static struct dahdi_ring_cadence cadences[NUM_CADENCE_MAX] = {
401
static struct dahdi_ring_cadence cadences[NUM_CADENCE_MAX] = {
402
	{ { 125, 125, 2000, 4000 } },			/*!< Quick chirp followed by normal ring */
402
	{ { 125, 125, 2000, 4000 } },			/*!< Quick chirp followed by normal ring */
403
	{ { 250, 250, 500, 1000, 250, 250, 500, 4000 } }, /*!< British style ring */
403
	{ { 250, 250, 500, 1000, 250, 250, 500, 4000 } }, /*!< British style ring */
404
	{ { 125, 125, 125, 125, 125, 4000 } },	/*!< Three short bursts */
404
	{ { 125, 125, 125, 125, 125, 4000 } },	/*!< Three short bursts */
405
	{ { 1000, 500, 2500, 5000 } },	/*!< Long ring */
405
	{ { 1000, 500, 2500, 5000 } },	/*!< Long ring */
406
};
406
};
407

    
   
407

   
408
/*! \brief cidrings says in which pause to transmit the cid information, where the first pause
408
/*! \brief cidrings says in which pause to transmit the cid information, where the first pause
409
 * is 1, the second pause is 2 and so on.
409
 * is 1, the second pause is 2 and so on.
410
 */
410
 */
411

    
   
411

   
412
static int cidrings[NUM_CADENCE_MAX] = {
412
static int cidrings[NUM_CADENCE_MAX] = {
413
	2,										/*!< Right after first long ring */
413
	2,										/*!< Right after first long ring */
414
	4,										/*!< Right after long part */
414
	4,										/*!< Right after long part */
415
	3,										/*!< After third chirp */
415
	3,										/*!< After third chirp */
416
	2,										/*!< Second spell */
416
	2,										/*!< Second spell */
417
};
417
};
418

    
   
418

   
419
/* ETSI EN300 659-1 specifies the ring pulse between 200 and 300 mS */
419
/* ETSI EN300 659-1 specifies the ring pulse between 200 and 300 mS */
420
static struct dahdi_ring_cadence AS_RP_cadence = {{250, 10000}};
420
static struct dahdi_ring_cadence AS_RP_cadence = {{250, 10000}};
421

    
   
421

   
422
#define ISTRUNK(p) ((p->sig == SIG_FXSLS) || (p->sig == SIG_FXSKS) || \
422
#define ISTRUNK(p) ((p->sig == SIG_FXSLS) || (p->sig == SIG_FXSKS) || \
423
			(p->sig == SIG_FXSGS) || (p->sig == SIG_PRI))
423
			(p->sig == SIG_FXSGS) || (p->sig == SIG_PRI))
424

    
   
424

   
425
#define CANBUSYDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __DAHDI_SIG_FXO) */)
425
#define CANBUSYDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __DAHDI_SIG_FXO) */)
426
#define CANPROGRESSDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __DAHDI_SIG_FXO) */)
426
#define CANPROGRESSDETECT(p) (ISTRUNK(p) || (p->sig & (SIG_EM | SIG_EM_E1 | SIG_SF)) /* || (p->sig & __DAHDI_SIG_FXO) */)
427

    
   
427

   
428
static char defaultcic[64] = "";
428
static char defaultcic[64] = "";
429
static char defaultozz[64] = "";
429
static char defaultozz[64] = "";
430

    
   
430

   
431
/*! Run this script when the MWI state changes on an FXO line, if mwimonitor is enabled */
431
/*! Run this script when the MWI state changes on an FXO line, if mwimonitor is enabled */
432
static char mwimonitornotify[PATH_MAX] = "";
432
static char mwimonitornotify[PATH_MAX] = "";
433
#ifndef HAVE_DAHDI_LINEREVERSE_VMWI
433
#ifndef HAVE_DAHDI_LINEREVERSE_VMWI
434
static int  mwisend_rpas = 0;
434
static int  mwisend_rpas = 0;
435
#endif
435
#endif
436

    
   
436

   
437
static char progzone[10] = "";
437
static char progzone[10] = "";
438

    
   
438

   
439
static int usedistinctiveringdetection = 0;
439
static int usedistinctiveringdetection = 0;
440
static int distinctiveringaftercid = 0;
440
static int distinctiveringaftercid = 0;
441

    
   
441

   
442
static int numbufs = 4;
442
static int numbufs = 4;
443

    
   
443

   
444
static int mwilevel = 512;
444
static int mwilevel = 512;
445
static int dtmfcid_level = 256;
445
static int dtmfcid_level = 256;
446

    
   
446

   
447
#define REPORT_CHANNEL_ALARMS 1
447
#define REPORT_CHANNEL_ALARMS 1
448
#define REPORT_SPAN_ALARMS    2 
448
#define REPORT_SPAN_ALARMS    2 
449
static int report_alarms = REPORT_CHANNEL_ALARMS;
449
static int report_alarms = REPORT_CHANNEL_ALARMS;
450

    
   
450

   
451
#ifdef HAVE_PRI
451
#ifdef HAVE_PRI
452
static int pridebugfd = -1;
452
static int pridebugfd = -1;
453
static char pridebugfilename[1024] = "";
453
static char pridebugfilename[1024] = "";
454
#endif
454
#endif
455

    
   
455

   
456
/*! \brief Wait up to 16 seconds for first digit (FXO logic) */
456
/*! \brief Wait up to 16 seconds for first digit (FXO logic) */
457
static int firstdigittimeout = 16000;
457
static int firstdigittimeout = 16000;
458

    
   
458

   
459
/*! \brief How long to wait for following digits (FXO logic) */
459
/*! \brief How long to wait for following digits (FXO logic) */
460
static int gendigittimeout = 8000;
460
static int gendigittimeout = 8000;
461

    
   
461

   
462
/*! \brief How long to wait for an extra digit, if there is an ambiguous match */
462
/*! \brief How long to wait for an extra digit, if there is an ambiguous match */
463
static int matchdigittimeout = 3000;
463
static int matchdigittimeout = 3000;
464

    
   
464

   
465
/*! \brief Protect the interface list (of dahdi_pvt's) */
465
/*! \brief Protect the interface list (of dahdi_pvt's) */
466
AST_MUTEX_DEFINE_STATIC(iflock);
466
AST_MUTEX_DEFINE_STATIC(iflock);
467

    
   
467

   
468

    
   
468

   
469
static int ifcount = 0;
469
static int ifcount = 0;
470

    
   
470

   
471
#ifdef HAVE_PRI
471
#ifdef HAVE_PRI
472
AST_MUTEX_DEFINE_STATIC(pridebugfdlock);
472
AST_MUTEX_DEFINE_STATIC(pridebugfdlock);
473
#endif
473
#endif
474

    
   
474

   
475
/*! \brief Protect the monitoring thread, so only one process can kill or start it, and not
475
/*! \brief Protect the monitoring thread, so only one process can kill or start it, and not
476
   when it's doing something critical. */
476
   when it's doing something critical. */
477
AST_MUTEX_DEFINE_STATIC(monlock);
477
AST_MUTEX_DEFINE_STATIC(monlock);
478

    
   
478

   
479
/*! \brief This is the thread for the monitor which checks for input on the channels
479
/*! \brief This is the thread for the monitor which checks for input on the channels
480
   which are not currently in use. */
480
   which are not currently in use. */
481
static pthread_t monitor_thread = AST_PTHREADT_NULL;
481
static pthread_t monitor_thread = AST_PTHREADT_NULL;
482
static ast_cond_t ss_thread_complete;
482
static ast_cond_t ss_thread_complete;
483
AST_MUTEX_DEFINE_STATIC(ss_thread_lock);
483
AST_MUTEX_DEFINE_STATIC(ss_thread_lock);
484
AST_MUTEX_DEFINE_STATIC(restart_lock);
484
AST_MUTEX_DEFINE_STATIC(restart_lock);
485
static int ss_thread_count = 0;
485
static int ss_thread_count = 0;
486
static int num_restart_pending = 0;
486
static int num_restart_pending = 0;
487

    
   
487

   
488
static int restart_monitor(void);
488
static int restart_monitor(void);
489

    
   
489

   
490
static enum ast_bridge_result dahdi_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms);
490
static enum ast_bridge_result dahdi_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms);
491

    
   
491

   
492
static int dahdi_sendtext(struct ast_channel *c, const char *text);
492
static int dahdi_sendtext(struct ast_channel *c, const char *text);
493

    
   
493

   
494
static void mwi_event_cb(const struct ast_event *event, void *userdata)
494
static void mwi_event_cb(const struct ast_event *event, void *userdata)
495
{
495
{
496
	/* This module does not handle MWI in an event-based manner.  However, it
496
	/* This module does not handle MWI in an event-based manner.  However, it
497
	 * subscribes to MWI for each mailbox that is configured so that the core
497
	 * subscribes to MWI for each mailbox that is configured so that the core
498
	 * knows that we care about it.  Then, chan_dahdi will get the MWI from the
498
	 * knows that we care about it.  Then, chan_dahdi will get the MWI from the
499
	 * event cache instead of checking the mailbox directly. */
499
	 * event cache instead of checking the mailbox directly. */
500
}
500
}
501

    
   
501

   
502
/*! \brief Avoid the silly dahdi_getevent which ignores a bunch of events */
502
/*! \brief Avoid the silly dahdi_getevent which ignores a bunch of events */
503
static inline int dahdi_get_event(int fd)
503
static inline int dahdi_get_event(int fd)
504
{
504
{
505
	int j;
505
	int j;
506
	if (ioctl(fd, DAHDI_GETEVENT, &j) == -1)
506
	if (ioctl(fd, DAHDI_GETEVENT, &j) == -1)
507
		return -1;
507
		return -1;
508
	return j;
508
	return j;
509
}
509
}
510

    
   
510

   
511
/*! \brief Avoid the silly dahdi_waitevent which ignores a bunch of events */
511
/*! \brief Avoid the silly dahdi_waitevent which ignores a bunch of events */
512
static inline int dahdi_wait_event(int fd)
512
static inline int dahdi_wait_event(int fd)
513
{
513
{
514
	int i, j = 0;
514
	int i, j = 0;
515
	i = DAHDI_IOMUX_SIGEVENT;
515
	i = DAHDI_IOMUX_SIGEVENT;
516
	if (ioctl(fd, DAHDI_IOMUX, &i) == -1)
516
	if (ioctl(fd, DAHDI_IOMUX, &i) == -1)
517
		return -1;
517
		return -1;
518
	if (ioctl(fd, DAHDI_GETEVENT, &j) == -1)
518
	if (ioctl(fd, DAHDI_GETEVENT, &j) == -1)
519
		return -1;
519
		return -1;
520
	return j;
520
	return j;
521
}
521
}
522

    
   
522

   
523
/*! Chunk size to read -- we use 20ms chunks to make things happy. */
523
/*! Chunk size to read -- we use 20ms chunks to make things happy. */
524
#define READ_SIZE 160
524
#define READ_SIZE 160
525

    
   
525

   
526
#define MASK_AVAIL		(1 << 0)	/*!< Channel available for PRI use */
526
#define MASK_AVAIL		(1 << 0)	/*!< Channel available for PRI use */
527
#define MASK_INUSE		(1 << 1)	/*!< Channel currently in use */
527
#define MASK_INUSE		(1 << 1)	/*!< Channel currently in use */
528

    
   
528

   
529
#define CALLWAITING_SILENT_SAMPLES		((300 * 8) / READ_SIZE) /*!< 300 ms */
529
#define CALLWAITING_SILENT_SAMPLES		((300 * 8) / READ_SIZE) /*!< 300 ms */
530
#define CALLWAITING_REPEAT_SAMPLES		((10000 * 8) / READ_SIZE) /*!< 10,000 ms */
530
#define CALLWAITING_REPEAT_SAMPLES		((10000 * 8) / READ_SIZE) /*!< 10,000 ms */
531
#define CALLWAITING_SUPPRESS_SAMPLES	((100 * 8) / READ_SIZE) /*!< 100 ms */
531
#define CALLWAITING_SUPPRESS_SAMPLES	((100 * 8) / READ_SIZE) /*!< 100 ms */
532
#define CIDCW_EXPIRE_SAMPLES			((500 * 8) / READ_SIZE) /*!< 500 ms */
532
#define CIDCW_EXPIRE_SAMPLES			((500 * 8) / READ_SIZE) /*!< 500 ms */
533
#define MIN_MS_SINCE_FLASH				((2000) )	/*!< 2000 ms */
533
#define MIN_MS_SINCE_FLASH				((2000) )	/*!< 2000 ms */
534
#define DEFAULT_RINGT 					((8000 * 8) / READ_SIZE) /*!< 8,000 ms */
534
#define DEFAULT_RINGT 					((8000 * 8) / READ_SIZE) /*!< 8,000 ms */
535

    
   
535

   
536
struct dahdi_pvt;
536
struct dahdi_pvt;
537

    
   
537

   
538
/*!
538
/*!
539
 * \brief Configured ring timeout base.
539
 * \brief Configured ring timeout base.
540
 * \note Value computed from "ringtimeout" read in from chan_dahdi.conf if it exists.
540
 * \note Value computed from "ringtimeout" read in from chan_dahdi.conf if it exists.
541
 */
541
 */
542
static int ringt_base = DEFAULT_RINGT;
542
static int ringt_base = DEFAULT_RINGT;
543

    
   
543

   
544
#if defined(HAVE_SS7)
544
#if defined(HAVE_SS7)
545

    
   
545

   
546
struct dahdi_ss7 {
546
struct dahdi_ss7 {
547
	struct sig_ss7_linkset ss7;
547
	struct sig_ss7_linkset ss7;
548
};
548
};
549

    
   
549

   
550
static struct dahdi_ss7 linksets[NUM_SPANS];
550
static struct dahdi_ss7 linksets[NUM_SPANS];
551

    
   
551

   
552
static int cur_ss7type = -1;
552
static int cur_ss7type = -1;
553
static int cur_linkset = -1;
553
static int cur_linkset = -1;
554
static int cur_pointcode = -1;
554
static int cur_pointcode = -1;
555
static int cur_cicbeginswith = -1;
555
static int cur_cicbeginswith = -1;
556
static int cur_adjpointcode = -1;
556
static int cur_adjpointcode = -1;
557
static int cur_networkindicator = -1;
557
static int cur_networkindicator = -1;
558
static int cur_defaultdpc = -1;
558
static int cur_defaultdpc = -1;
559
#endif	/* defined(HAVE_SS7) */
559
#endif	/* defined(HAVE_SS7) */
560

    
   
560

   
561
#ifdef HAVE_OPENR2
561
#ifdef HAVE_OPENR2
562
struct dahdi_mfcr2 {
562
struct dahdi_mfcr2 {
563
	pthread_t r2master;		       /*!< Thread of master */
563
	pthread_t r2master;		       /*!< Thread of master */
564
	openr2_context_t *protocol_context;    /*!< OpenR2 context handle */
564
	openr2_context_t *protocol_context;    /*!< OpenR2 context handle */
565
	struct dahdi_pvt *pvts[SIG_MFCR2_MAX_CHANNELS];     /*!< Member channel pvt structs */
565
	struct dahdi_pvt *pvts[SIG_MFCR2_MAX_CHANNELS];     /*!< Member channel pvt structs */
566
	int numchans;                          /*!< Number of channels in this R2 block */
566
	int numchans;                          /*!< Number of channels in this R2 block */
567
	int monitored_count;                   /*!< Number of channels being monitored */
567
	int monitored_count;                   /*!< Number of channels being monitored */
568
};
568
};
569

    
   
569

   
570
struct dahdi_mfcr2_conf {
570
struct dahdi_mfcr2_conf {
571
	openr2_variant_t variant;
571
	openr2_variant_t variant;
572
	int mfback_timeout;
572
	int mfback_timeout;
573
	int metering_pulse_timeout;
573
	int metering_pulse_timeout;
574
	int max_ani;
574
	int max_ani;
575
	int max_dnis;
575
	int max_dnis;
576
#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
576
#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
577
	int dtmf_time_on;
577
	int dtmf_time_on;
578
	int dtmf_time_off;
578
	int dtmf_time_off;
579
#endif
579
#endif
580
#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 3
580
#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 3
581
	int dtmf_end_timeout;
581
	int dtmf_end_timeout;
582
#endif
582
#endif
583
	signed int get_ani_first:2;
583
	signed int get_ani_first:2;
584
#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
584
#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
585
	signed int skip_category_request:2;
585
	signed int skip_category_request:2;
586
#endif
586
#endif
587
	unsigned int call_files:1;
587
	unsigned int call_files:1;
588
	unsigned int allow_collect_calls:1;
588
	unsigned int allow_collect_calls:1;
589
	unsigned int charge_calls:1;
589
	unsigned int charge_calls:1;
590
	unsigned int accept_on_offer:1;
590
	unsigned int accept_on_offer:1;
591
	unsigned int forced_release:1;
591
	unsigned int forced_release:1;
592
	unsigned int double_answer:1;
592
	unsigned int double_answer:1;
593
	signed int immediate_accept:2;
593
	signed int immediate_accept:2;
594
#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
594
#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
595
	signed int dtmf_dialing:2;
595
	signed int dtmf_dialing:2;
596
	signed int dtmf_detection:2;
596
	signed int dtmf_detection:2;
597
#endif
597
#endif
598
	char logdir[OR2_MAX_PATH];
598
	char logdir[OR2_MAX_PATH];
599
	char r2proto_file[OR2_MAX_PATH];
599
	char r2proto_file[OR2_MAX_PATH];
600
	openr2_log_level_t loglevel;
600
	openr2_log_level_t loglevel;
601
	openr2_calling_party_category_t category;
601
	openr2_calling_party_category_t category;
602
};
602
};
603

    
   
603

   
604
/* malloc'd array of malloc'd r2links */
604
/* malloc'd array of malloc'd r2links */
605
static struct dahdi_mfcr2 **r2links;
605
static struct dahdi_mfcr2 **r2links;
606
/* how many r2links have been malloc'd */
606
/* how many r2links have been malloc'd */
607
static int r2links_count = 0;
607
static int r2links_count = 0;
608

    
   
608

   
609
#endif /* HAVE_OPENR2 */
609
#endif /* HAVE_OPENR2 */
610

    
   
610

   
611
#ifdef HAVE_PRI
611
#ifdef HAVE_PRI
612

    
   
612

   
613
struct dahdi_pri {
613
struct dahdi_pri {
614
	int dchannels[SIG_PRI_NUM_DCHANS];		/*!< What channel are the dchannels on */
614
	int dchannels[SIG_PRI_NUM_DCHANS];		/*!< What channel are the dchannels on */
615
	int mastertrunkgroup;					/*!< What trunk group is our master */
615
	int mastertrunkgroup;					/*!< What trunk group is our master */
616
	int prilogicalspan;						/*!< Logical span number within trunk group */
616
	int prilogicalspan;						/*!< Logical span number within trunk group */
617
	struct sig_pri_span pri;
617
	struct sig_pri_span pri;
618
};
618
};
619

    
   
619

   
620
static struct dahdi_pri pris[NUM_SPANS];
620
static struct dahdi_pri pris[NUM_SPANS];
621

    
   
621

   
622
#if defined(HAVE_PRI_CCSS)
622
#if defined(HAVE_PRI_CCSS)
623
/*! DAHDI PRI CCSS agent and monitor type name. */
623
/*! DAHDI PRI CCSS agent and monitor type name. */
624
static const char dahdi_pri_cc_type[] = "DAHDI/PRI";
624
static const char dahdi_pri_cc_type[] = "DAHDI/PRI";
625
#endif	/* defined(HAVE_PRI_CCSS) */
625
#endif	/* defined(HAVE_PRI_CCSS) */
626

    
   
626

   
627
#else
627
#else
628
/*! Shut up the compiler */
628
/*! Shut up the compiler */
629
struct dahdi_pri;
629
struct dahdi_pri;
630
#endif
630
#endif
631

    
   
631

   
632
#define SUB_REAL	0			/*!< Active call */
632
#define SUB_REAL	0			/*!< Active call */
633
#define SUB_CALLWAIT	1			/*!< Call-Waiting call on hold */
633
#define SUB_CALLWAIT	1			/*!< Call-Waiting call on hold */
634
#define SUB_THREEWAY	2			/*!< Three-way call */
634
#define SUB_THREEWAY	2			/*!< Three-way call */
635

    
   
635

   
636
/* Polarity states */
636
/* Polarity states */
637
#define POLARITY_IDLE   0
637
#define POLARITY_IDLE   0
638
#define POLARITY_REV    1
638
#define POLARITY_REV    1
639

    
   
639

   
640

    
   
640

   
641
struct distRingData {
641
struct distRingData {
642
	int ring[3];
642
	int ring[3];
643
	int range;
643
	int range;
644
};
644
};
645
struct ringContextData {
645
struct ringContextData {
646
	char contextData[AST_MAX_CONTEXT];
646
	char contextData[AST_MAX_CONTEXT];
647
};
647
};
648
struct dahdi_distRings {
648
struct dahdi_distRings {
649
	struct distRingData ringnum[3];
649
	struct distRingData ringnum[3];
650
	struct ringContextData ringContext[3];
650
	struct ringContextData ringContext[3];
651
};
651
};
652

    
   
652

   
653
static const char * const subnames[] = {
653
static const char * const subnames[] = {
654
	"Real",
654
	"Real",
655
	"Callwait",
655
	"Callwait",
656
	"Threeway"
656
	"Threeway"
657
};
657
};
658

    
   
658

   
659
struct dahdi_subchannel {
659
struct dahdi_subchannel {
660
	int dfd;
660
	int dfd;
661
	struct ast_channel *owner;
661
	struct ast_channel *owner;
662
	int chan;
662
	int chan;
663
	short buffer[AST_FRIENDLY_OFFSET/2 + READ_SIZE];
663
	short buffer[AST_FRIENDLY_OFFSET/2 + READ_SIZE];
664
	struct ast_frame f;		/*!< One frame for each channel.  How did this ever work before? */
664
	struct ast_frame f;		/*!< One frame for each channel.  How did this ever work before? */
665
	unsigned int needringing:1;
665
	unsigned int needringing:1;
666
	unsigned int needbusy:1;
666
	unsigned int needbusy:1;
667
	unsigned int needcongestion:1;
667
	unsigned int needcongestion:1;
668
	unsigned int needanswer:1;
668
	unsigned int needanswer:1;
669
	unsigned int needflash:1;
669
	unsigned int needflash:1;
670
	unsigned int needhold:1;
670
	unsigned int needhold:1;
671
	unsigned int needunhold:1;
671
	unsigned int needunhold:1;
672
	unsigned int linear:1;
672
	unsigned int linear:1;
673
	unsigned int inthreeway:1;
673
	unsigned int inthreeway:1;
674
	struct dahdi_confinfo curconf;
674
	struct dahdi_confinfo curconf;
675
};
675
};
676

    
   
676

   
677
#define CONF_USER_REAL		(1 << 0)
677
#define CONF_USER_REAL		(1 << 0)
678
#define CONF_USER_THIRDCALL	(1 << 1)
678
#define CONF_USER_THIRDCALL	(1 << 1)
679

    
   
679

   
680
#define MAX_SLAVES	4
680
#define MAX_SLAVES	4
681

    
   
681

   
682
/* States for sending MWI message
682
/* States for sending MWI message
683
 * First three states are required for send Ring Pulse Alert Signal
683
 * First three states are required for send Ring Pulse Alert Signal
684
 */
684
 */
685
typedef enum {
685
typedef enum {
686
	MWI_SEND_NULL = 0,
686
	MWI_SEND_NULL = 0,
687
	MWI_SEND_SA,
687
	MWI_SEND_SA,
688
	MWI_SEND_SA_WAIT,
688
	MWI_SEND_SA_WAIT,
689
	MWI_SEND_PAUSE,
689
	MWI_SEND_PAUSE,
690
	MWI_SEND_SPILL,
690
	MWI_SEND_SPILL,
691
	MWI_SEND_CLEANUP,
691
	MWI_SEND_CLEANUP,
692
	MWI_SEND_DONE,
692
	MWI_SEND_DONE,
693
} mwisend_states;
693
} mwisend_states;
694

    
   
694

   
695
struct mwisend_info {
695
struct mwisend_info {
696
	struct	timeval	pause;
696
	struct	timeval	pause;
697
	mwisend_states 	mwisend_current;
697
	mwisend_states 	mwisend_current;
698
};
698
};
699

    
   
699

   
700
/*! Specify the lists dahdi_pvt can be put in. */
700
/*! Specify the lists dahdi_pvt can be put in. */
701
enum DAHDI_IFLIST {
701
enum DAHDI_IFLIST {
702
	DAHDI_IFLIST_NONE,	/*!< The dahdi_pvt is not in any list. */
702
	DAHDI_IFLIST_NONE,	/*!< The dahdi_pvt is not in any list. */
703
	DAHDI_IFLIST_MAIN,	/*!< The dahdi_pvt is in the main interface list */
703
	DAHDI_IFLIST_MAIN,	/*!< The dahdi_pvt is in the main interface list */
704
#if defined(HAVE_PRI)
704
#if defined(HAVE_PRI)
705
	DAHDI_IFLIST_NO_B_CHAN,	/*!< The dahdi_pvt is in a no B channel interface list */
705
	DAHDI_IFLIST_NO_B_CHAN,	/*!< The dahdi_pvt is in a no B channel interface list */
706
#endif	/* defined(HAVE_PRI) */
706
#endif	/* defined(HAVE_PRI) */
707
};
707
};
708

    
   
708

   
709
struct dahdi_pvt {
709
struct dahdi_pvt {
710
	ast_mutex_t lock;					/*!< Channel private lock. */
710
	ast_mutex_t lock;					/*!< Channel private lock. */
711
	struct callerid_state *cs;
711
	struct callerid_state *cs;
712
	struct ast_channel *owner;			/*!< Our current active owner (if applicable) */
712
	struct ast_channel *owner;			/*!< Our current active owner (if applicable) */
713
							/*!< Up to three channels can be associated with this call */
713
							/*!< Up to three channels can be associated with this call */
714

    
   
714

   
715
	struct dahdi_subchannel sub_unused;		/*!< Just a safety precaution */
715
	struct dahdi_subchannel sub_unused;		/*!< Just a safety precaution */
716
	struct dahdi_subchannel subs[3];			/*!< Sub-channels */
716
	struct dahdi_subchannel subs[3];			/*!< Sub-channels */
717
	struct dahdi_confinfo saveconf;			/*!< Saved conference info */
717
	struct dahdi_confinfo saveconf;			/*!< Saved conference info */
718

    
   
718

   
719
	struct dahdi_pvt *slaves[MAX_SLAVES];		/*!< Slave to us (follows our conferencing) */
719
	struct dahdi_pvt *slaves[MAX_SLAVES];		/*!< Slave to us (follows our conferencing) */
720
	struct dahdi_pvt *master;				/*!< Master to us (we follow their conferencing) */
720
	struct dahdi_pvt *master;				/*!< Master to us (we follow their conferencing) */
721
	int inconference;				/*!< If our real should be in the conference */
721
	int inconference;				/*!< If our real should be in the conference */
722

    
   
722

   
723
	int bufsize;                /*!< Size of the buffers */
723
	int bufsize;                /*!< Size of the buffers */
724
	int buf_no;					/*!< Number of buffers */
724
	int buf_no;					/*!< Number of buffers */
725
	int buf_policy;				/*!< Buffer policy */
725
	int buf_policy;				/*!< Buffer policy */
726
	int faxbuf_no;              /*!< Number of Fax buffers */
726
	int faxbuf_no;              /*!< Number of Fax buffers */
727
	int faxbuf_policy;          /*!< Fax buffer policy */
727
	int faxbuf_policy;          /*!< Fax buffer policy */
728
	int sig;					/*!< Signalling style */
728
	int sig;					/*!< Signalling style */
729
	/*!
729
	/*!
730
	 * \brief Nonzero if the signaling type is sent over a radio.
730
	 * \brief Nonzero if the signaling type is sent over a radio.
731
	 * \note Set to a couple of nonzero values but it is only tested like a boolean.
731
	 * \note Set to a couple of nonzero values but it is only tested like a boolean.
732
	 */
732
	 */
733
	int radio;
733
	int radio;
734
	int outsigmod;					/*!< Outbound Signalling style (modifier) */
734
	int outsigmod;					/*!< Outbound Signalling style (modifier) */
735
	int oprmode;					/*!< "Operator Services" mode */
735
	int oprmode;					/*!< "Operator Services" mode */
736
	struct dahdi_pvt *oprpeer;				/*!< "Operator Services" peer tech_pvt ptr */
736
	struct dahdi_pvt *oprpeer;				/*!< "Operator Services" peer tech_pvt ptr */
737
	/*! \brief Amount of gain to increase during caller id */
737
	/*! \brief Amount of gain to increase during caller id */
738
	float cid_rxgain;
738
	float cid_rxgain;
739
	/*! \brief Rx gain set by chan_dahdi.conf */
739
	/*! \brief Rx gain set by chan_dahdi.conf */
740
	float rxgain;
740
	float rxgain;
741
	/*! \brief Tx gain set by chan_dahdi.conf */
741
	/*! \brief Tx gain set by chan_dahdi.conf */
742
	float txgain;
742
	float txgain;
743

    
   
743

   
744
	float txdrc; /*!< Dynamic Range Compression factor. a number between 1 and 6ish */
744
	float txdrc; /*!< Dynamic Range Compression factor. a number between 1 and 6ish */
745
	float rxdrc;
745
	float rxdrc;
746
	
746
	
747
	int tonezone;					/*!< tone zone for this chan, or -1 for default */
747
	int tonezone;					/*!< tone zone for this chan, or -1 for default */
748
	enum DAHDI_IFLIST which_iflist;	/*!< Which interface list is this structure listed? */
748
	enum DAHDI_IFLIST which_iflist;	/*!< Which interface list is this structure listed? */
749
	struct dahdi_pvt *next;				/*!< Next channel in list */
749
	struct dahdi_pvt *next;				/*!< Next channel in list */
750
	struct dahdi_pvt *prev;				/*!< Prev channel in list */
750
	struct dahdi_pvt *prev;				/*!< Prev channel in list */
751

    
   
751

   
752
	/* flags */
752
	/* flags */
753

    
   
753

   
754
	/*!
754
	/*!
755
	 * \brief TRUE if ADSI (Analog Display Services Interface) available
755
	 * \brief TRUE if ADSI (Analog Display Services Interface) available
756
	 * \note Set from the "adsi" value read in from chan_dahdi.conf
756
	 * \note Set from the "adsi" value read in from chan_dahdi.conf
757
	 */
757
	 */
758
	unsigned int adsi:1;
758
	unsigned int adsi:1;
759
	/*!
759
	/*!
760
	 * \brief TRUE if we can use a polarity reversal to mark when an outgoing
760
	 * \brief TRUE if we can use a polarity reversal to mark when an outgoing
761
	 * call is answered by the remote party.
761
	 * call is answered by the remote party.
762
	 * \note Set from the "answeronpolarityswitch" value read in from chan_dahdi.conf
762
	 * \note Set from the "answeronpolarityswitch" value read in from chan_dahdi.conf
763
	 */
763
	 */
764
	unsigned int answeronpolarityswitch:1;
764
	unsigned int answeronpolarityswitch:1;
765
	/*!
765
	/*!
766
	 * \brief TRUE if busy detection is enabled.
766
	 * \brief TRUE if busy detection is enabled.
767
	 * (Listens for the beep-beep busy pattern.)
767
	 * (Listens for the beep-beep busy pattern.)
768
	 * \note Set from the "busydetect" value read in from chan_dahdi.conf
768
	 * \note Set from the "busydetect" value read in from chan_dahdi.conf
769
	 */
769
	 */
770
	unsigned int busydetect:1;
770
	unsigned int busydetect:1;
771
	/*!
771
	/*!
772
	 * \brief TRUE if call return is enabled.
772
	 * \brief TRUE if call return is enabled.
773
	 * (*69, if your dialplan doesn't catch this first)
773
	 * (*69, if your dialplan doesn't catch this first)
774
	 * \note Set from the "callreturn" value read in from chan_dahdi.conf
774
	 * \note Set from the "callreturn" value read in from chan_dahdi.conf
775
	 */
775
	 */
776
	unsigned int callreturn:1;
776
	unsigned int callreturn:1;
777
	/*!
777
	/*!
778
	 * \brief TRUE if busy extensions will hear the call-waiting tone
778
	 * \brief TRUE if busy extensions will hear the call-waiting tone
779
	 * and can use hook-flash to switch between callers.
779
	 * and can use hook-flash to switch between callers.
780
	 * \note Can be disabled by dialing *70.
780
	 * \note Can be disabled by dialing *70.
781
	 * \note Initialized with the "callwaiting" value read in from chan_dahdi.conf
781
	 * \note Initialized with the "callwaiting" value read in from chan_dahdi.conf
782
	 */
782
	 */
783
	unsigned int callwaiting:1;
783
	unsigned int callwaiting:1;
784
	/*!
784
	/*!
785
	 * \brief TRUE if send caller ID for Call Waiting
785
	 * \brief TRUE if send caller ID for Call Waiting
786
	 * \note Set from the "callwaitingcallerid" value read in from chan_dahdi.conf
786
	 * \note Set from the "callwaitingcallerid" value read in from chan_dahdi.conf
787
	 */
787
	 */
788
	unsigned int callwaitingcallerid:1;
788
	unsigned int callwaitingcallerid:1;
789
	/*!
789
	/*!
790
	 * \brief TRUE if support for call forwarding enabled.
790
	 * \brief TRUE if support for call forwarding enabled.
791
	 * Dial *72 to enable call forwarding.
791
	 * Dial *72 to enable call forwarding.
792
	 * Dial *73 to disable call forwarding.
792
	 * Dial *73 to disable call forwarding.
793
	 * \note Set from the "cancallforward" value read in from chan_dahdi.conf
793
	 * \note Set from the "cancallforward" value read in from chan_dahdi.conf
794
	 */
794
	 */
795
	unsigned int cancallforward:1;
795
	unsigned int cancallforward:1;
796
	/*!
796
	/*!
797
	 * \brief TRUE if support for call parking is enabled.
797
	 * \brief TRUE if support for call parking is enabled.
798
	 * \note Set from the "canpark" value read in from chan_dahdi.conf
798
	 * \note Set from the "canpark" value read in from chan_dahdi.conf
799
	 */
799
	 */
800
	unsigned int canpark:1;
800
	unsigned int canpark:1;
801
	/*! \brief TRUE if to wait for a DTMF digit to confirm answer */
801
	/*! \brief TRUE if to wait for a DTMF digit to confirm answer */
802
	unsigned int confirmanswer:1;
802
	unsigned int confirmanswer:1;
803
	/*!
803
	/*!
804
	 * \brief TRUE if the channel is to be destroyed on hangup.
804
	 * \brief TRUE if the channel is to be destroyed on hangup.
805
	 * (Used by pseudo channels.)
805
	 * (Used by pseudo channels.)
806
	 */
806
	 */
807
	unsigned int destroy:1;
807
	unsigned int destroy:1;
808
	unsigned int didtdd:1;				/*!< flag to say its done it once */
808
	unsigned int didtdd:1;				/*!< flag to say its done it once */
809
	/*! \brief TRUE if analog type line dialed no digits in Dial() */
809
	/*! \brief TRUE if analog type line dialed no digits in Dial() */
810
	unsigned int dialednone:1;
810
	unsigned int dialednone:1;
811
	/*!
811
	/*!
812
	 * \brief TRUE if in the process of dialing digits or sending something.
812
	 * \brief TRUE if in the process of dialing digits or sending something.
813
	 * \note This is used as a receive squelch for ISDN until connected.
813
	 * \note This is used as a receive squelch for ISDN until connected.
814
	 */
814
	 */
815
	unsigned int dialing:1;
815
	unsigned int dialing:1;
816
	/*! \brief TRUE if the transfer capability of the call is digital. */
816
	/*! \brief TRUE if the transfer capability of the call is digital. */
817
	unsigned int digital:1;
817
	unsigned int digital:1;
818
	/*! \brief TRUE if Do-Not-Disturb is enabled, present only for non sig_analog */
818
	/*! \brief TRUE if Do-Not-Disturb is enabled, present only for non sig_analog */
819
	unsigned int dnd:1;
819
	unsigned int dnd:1;
820
	/*! \brief XXX BOOLEAN Purpose??? */
820
	/*! \brief XXX BOOLEAN Purpose??? */
821
	unsigned int echobreak:1;
821
	unsigned int echobreak:1;
822
	/*!
822
	/*!
823
	 * \brief TRUE if echo cancellation enabled when bridged.
823
	 * \brief TRUE if echo cancellation enabled when bridged.
824
	 * \note Initialized with the "echocancelwhenbridged" value read in from chan_dahdi.conf
824
	 * \note Initialized with the "echocancelwhenbridged" value read in from chan_dahdi.conf
825
	 * \note Disabled if the echo canceller is not setup.
825
	 * \note Disabled if the echo canceller is not setup.
826
	 */
826
	 */
827
	unsigned int echocanbridged:1;
827
	unsigned int echocanbridged:1;
828
	/*! \brief TRUE if echo cancellation is turned on. */
828
	/*! \brief TRUE if echo cancellation is turned on. */
829
	unsigned int echocanon:1;
829
	unsigned int echocanon:1;
830
	/*! \brief TRUE if a fax tone has already been handled. */
830
	/*! \brief TRUE if a fax tone has already been handled. */
831
	unsigned int faxhandled:1;
831
	unsigned int faxhandled:1;
832
	/*! TRUE if dynamic faxbuffers are configured for use, default is OFF */
832
	/*! TRUE if dynamic faxbuffers are configured for use, default is OFF */
833
	unsigned int usefaxbuffers:1;
833
	unsigned int usefaxbuffers:1;
834
	/*! TRUE while buffer configuration override is in use */
834
	/*! TRUE while buffer configuration override is in use */
835
	unsigned int bufferoverrideinuse:1;
835
	unsigned int bufferoverrideinuse:1;
836
	/*! \brief TRUE if over a radio and dahdi_read() has been called. */
836
	/*! \brief TRUE if over a radio and dahdi_read() has been called. */
837
	unsigned int firstradio:1;
837
	unsigned int firstradio:1;
838
	/*!
838
	/*!
839
	 * \brief TRUE if the call will be considered "hung up" on a polarity reversal.
839
	 * \brief TRUE if the call will be considered "hung up" on a polarity reversal.
840
	 * \note Set from the "hanguponpolarityswitch" value read in from chan_dahdi.conf
840
	 * \note Set from the "hanguponpolarityswitch" value read in from chan_dahdi.conf
841
	 */
841
	 */
842
	unsigned int hanguponpolarityswitch:1;
842
	unsigned int hanguponpolarityswitch:1;
843
	/*! \brief TRUE if DTMF detection needs to be done by hardware. */
843
	/*! \brief TRUE if DTMF detection needs to be done by hardware. */
844
	unsigned int hardwaredtmf:1;
844
	unsigned int hardwaredtmf:1;
845
	/*!
845
	/*!
846
	 * \brief TRUE if the outgoing caller ID is blocked/hidden.
846
	 * \brief TRUE if the outgoing caller ID is blocked/hidden.
847
	 * \note Caller ID can be disabled by dialing *67.
847
	 * \note Caller ID can be disabled by dialing *67.
848
	 * \note Caller ID can be enabled by dialing *82.
848
	 * \note Caller ID can be enabled by dialing *82.
849
	 * \note Initialized with the "hidecallerid" value read in from chan_dahdi.conf
849
	 * \note Initialized with the "hidecallerid" value read in from chan_dahdi.conf
850
	 */
850
	 */
851
	unsigned int hidecallerid:1;
851
	unsigned int hidecallerid:1;
852
	/*!
852
	/*!
853
	 * \brief TRUE if hide just the name not the number for legacy PBX use.
853
	 * \brief TRUE if hide just the name not the number for legacy PBX use.
854
	 * \note Only applies to PRI channels.
854
	 * \note Only applies to PRI channels.
855
	 * \note Set from the "hidecalleridname" value read in from chan_dahdi.conf
855
	 * \note Set from the "hidecalleridname" value read in from chan_dahdi.conf
856
	 */
856
	 */
857
	unsigned int hidecalleridname:1;
857
	unsigned int hidecalleridname:1;
858
	/*! \brief TRUE if DTMF detection is disabled. */
858
	/*! \brief TRUE if DTMF detection is disabled. */
859
	unsigned int ignoredtmf:1;
859
	unsigned int ignoredtmf:1;
860
	/*!
860
	/*!
861
	 * \brief TRUE if the channel should be answered immediately
861
	 * \brief TRUE if the channel should be answered immediately
862
	 * without attempting to gather any digits.
862
	 * without attempting to gather any digits.
863
	 * \note Set from the "immediate" value read in from chan_dahdi.conf
863
	 * \note Set from the "immediate" value read in from chan_dahdi.conf
864
	 */
864
	 */
865
	unsigned int immediate:1;
865
	unsigned int immediate:1;
866
	/*! \brief TRUE if in an alarm condition. */
866
	/*! \brief TRUE if in an alarm condition. */
867
	unsigned int inalarm:1;
867
	unsigned int inalarm:1;
868
	/*! \brief TRUE if TDD in MATE mode */
868
	/*! \brief TRUE if TDD in MATE mode */
869
	unsigned int mate:1;
869
	unsigned int mate:1;
870
	/*! \brief TRUE if we originated the call leg. */
870
	/*! \brief TRUE if we originated the call leg. */
871
	unsigned int outgoing:1;
871
	unsigned int outgoing:1;
872
	/* unsigned int overlapdial:1; 			unused and potentially confusing */
872
	/* unsigned int overlapdial:1; 			unused and potentially confusing */
873
	/*!
873
	/*!
874
	 * \brief TRUE if busy extensions will hear the call-waiting tone
874
	 * \brief TRUE if busy extensions will hear the call-waiting tone
875
	 * and can use hook-flash to switch between callers.
875
	 * and can use hook-flash to switch between callers.
876
	 * \note Set from the "callwaiting" value read in from chan_dahdi.conf
876
	 * \note Set from the "callwaiting" value read in from chan_dahdi.conf
877
	 */
877
	 */
878
	unsigned int permcallwaiting:1;
878
	unsigned int permcallwaiting:1;
879
	/*!
879
	/*!
880
	 * \brief TRUE if the outgoing caller ID is blocked/restricted/hidden.
880
	 * \brief TRUE if the outgoing caller ID is blocked/restricted/hidden.
881
	 * \note Set from the "hidecallerid" value read in from chan_dahdi.conf
881
	 * \note Set from the "hidecallerid" value read in from chan_dahdi.conf
882
	 */
882
	 */
883
	unsigned int permhidecallerid:1;
883
	unsigned int permhidecallerid:1;
884
	/*!
884
	/*!
885
	 * \brief TRUE if PRI congestion/busy indications are sent out-of-band.
885
	 * \brief TRUE if PRI congestion/busy indications are sent out-of-band.
886
	 * \note Set from the "priindication" value read in from chan_dahdi.conf
886
	 * \note Set from the "priindication" value read in from chan_dahdi.conf
887
	 */
887
	 */
888
	unsigned int priindication_oob:1;
888
	unsigned int priindication_oob:1;
889
	/*!
889
	/*!
890
	 * \brief TRUE if PRI B channels are always exclusively selected.
890
	 * \brief TRUE if PRI B channels are always exclusively selected.
891
	 * \note Set from the "priexclusive" value read in from chan_dahdi.conf
891
	 * \note Set from the "priexclusive" value read in from chan_dahdi.conf
892
	 */
892
	 */
893
	unsigned int priexclusive:1;
893
	unsigned int priexclusive:1;
894
	/*!
894
	/*!
895
	 * \brief TRUE if we will pulse dial.
895
	 * \brief TRUE if we will pulse dial.
896
	 * \note Set from the "pulsedial" value read in from chan_dahdi.conf
896
	 * \note Set from the "pulsedial" value read in from chan_dahdi.conf
897
	 */
897
	 */
898
	unsigned int pulse:1;
898
	unsigned int pulse:1;
899
	/*! \brief TRUE if a pulsed digit was detected. (Pulse dial phone detected) */
899
	/*! \brief TRUE if a pulsed digit was detected. (Pulse dial phone detected) */
900
	unsigned int pulsedial:1;
900
	unsigned int pulsedial:1;
901
	unsigned int restartpending:1;		/*!< flag to ensure counted only once for restart */
901
	unsigned int restartpending:1;		/*!< flag to ensure counted only once for restart */
902
	/*!
902
	/*!
903
	 * \brief TRUE if caller ID is restricted.
903
	 * \brief TRUE if caller ID is restricted.
904
	 * \note Set but not used.  Should be deleted.  Redundant with permhidecallerid.
904
	 * \note Set but not used.  Should be deleted.  Redundant with permhidecallerid.
905
	 * \note Set from the "restrictcid" value read in from chan_dahdi.conf
905
	 * \note Set from the "restrictcid" value read in from chan_dahdi.conf
906
	 */
906
	 */
907
	unsigned int restrictcid:1;
907
	unsigned int restrictcid:1;
908
	/*!
908
	/*!
909
	 * \brief TRUE if three way calling is enabled
909
	 * \brief TRUE if three way calling is enabled
910
	 * \note Set from the "threewaycalling" value read in from chan_dahdi.conf
910
	 * \note Set from the "threewaycalling" value read in from chan_dahdi.conf
911
	 */
911
	 */
912
	unsigned int threewaycalling:1;
912
	unsigned int threewaycalling:1;
913
	/*!
913
	/*!
914
	 * \brief TRUE if call transfer is enabled
914
	 * \brief TRUE if call transfer is enabled
915
	 * \note For FXS ports (either direct analog or over T1/E1):
915
	 * \note For FXS ports (either direct analog or over T1/E1):
916
	 *   Support flash-hook call transfer
916
	 *   Support flash-hook call transfer
917
	 * \note For digital ports using ISDN PRI protocols:
917
	 * \note For digital ports using ISDN PRI protocols:
918
	 *   Support switch-side transfer (called 2BCT, RLT or other names)
918
	 *   Support switch-side transfer (called 2BCT, RLT or other names)
919
	 * \note Set from the "transfer" value read in from chan_dahdi.conf
919
	 * \note Set from the "transfer" value read in from chan_dahdi.conf
920
	 */
920
	 */
921
	unsigned int transfer:1;
921
	unsigned int transfer:1;
922
	/*!
922
	/*!
923
	 * \brief TRUE if caller ID is used on this channel.
923
	 * \brief TRUE if caller ID is used on this channel.
924
	 * \note PRI and SS7 spans will save caller ID from the networking peer.
924
	 * \note PRI and SS7 spans will save caller ID from the networking peer.
925
	 * \note FXS ports will generate the caller ID spill.
925
	 * \note FXS ports will generate the caller ID spill.
926
	 * \note FXO ports will listen for the caller ID spill.
926
	 * \note FXO ports will listen for the caller ID spill.
927
	 * \note Set from the "usecallerid" value read in from chan_dahdi.conf
927
	 * \note Set from the "usecallerid" value read in from chan_dahdi.conf
928
	 */
928
	 */
929
	unsigned int use_callerid:1;
929
	unsigned int use_callerid:1;
930
	/*!
930
	/*!
931
	 * \brief TRUE if we will use the calling presentation setting
931
	 * \brief TRUE if we will use the calling presentation setting
932
	 * from the Asterisk channel for outgoing calls.
932
	 * from the Asterisk channel for outgoing calls.
933
	 * \note Only applies to PRI and SS7 channels.
933
	 * \note Only applies to PRI and SS7 channels.
934
	 * \note Set from the "usecallingpres" value read in from chan_dahdi.conf
934
	 * \note Set from the "usecallingpres" value read in from chan_dahdi.conf
935
	 */
935
	 */
936
	unsigned int use_callingpres:1;
936
	unsigned int use_callingpres:1;
937
	/*!
937
	/*!
938
	 * \brief TRUE if distinctive rings are to be detected.
938
	 * \brief TRUE if distinctive rings are to be detected.
939
	 * \note For FXO lines
939
	 * \note For FXO lines
940
	 * \note Set indirectly from the "usedistinctiveringdetection" value read in from chan_dahdi.conf
940
	 * \note Set indirectly from the "usedistinctiveringdetection" value read in from chan_dahdi.conf
941
	 */
941
	 */
942
	unsigned int usedistinctiveringdetection:1;
942
	unsigned int usedistinctiveringdetection:1;
943
	/*!
943
	/*!
944
	 * \brief TRUE if we should use the callerid from incoming call on dahdi transfer.
944
	 * \brief TRUE if we should use the callerid from incoming call on dahdi transfer.
945
	 * \note Set from the "useincomingcalleridondahditransfer" value read in from chan_dahdi.conf
945
	 * \note Set from the "useincomingcalleridondahditransfer" value read in from chan_dahdi.conf
946
	 */
946
	 */
947
	unsigned int dahditrcallerid:1;
947
	unsigned int dahditrcallerid:1;
948
	/*!
948
	/*!
949
	 * \brief TRUE if allowed to flash-transfer to busy channels.
949
	 * \brief TRUE if allowed to flash-transfer to busy channels.
950
	 * \note Set from the "transfertobusy" value read in from chan_dahdi.conf
950
	 * \note Set from the "transfertobusy" value read in from chan_dahdi.conf
951
	 */
951
	 */
952
	unsigned int transfertobusy:1;
952
	unsigned int transfertobusy:1;
953
	/*!
953
	/*!
954
	 * \brief TRUE if the FXO port monitors for neon type MWI indications from the other end.
954
	 * \brief TRUE if the FXO port monitors for neon type MWI indications from the other end.
955
	 * \note Set if the "mwimonitor" value read in contains "neon" from chan_dahdi.conf
955
	 * \note Set if the "mwimonitor" value read in contains "neon" from chan_dahdi.conf
956
	 */
956
	 */
957
	unsigned int mwimonitor_neon:1;
957
	unsigned int mwimonitor_neon:1;
958
	/*!
958
	/*!
959
	 * \brief TRUE if the FXO port monitors for fsk type MWI indications from the other end.
959
	 * \brief TRUE if the FXO port monitors for fsk type MWI indications from the other end.
960
	 * \note Set if the "mwimonitor" value read in contains "fsk" from chan_dahdi.conf
960
	 * \note Set if the "mwimonitor" value read in contains "fsk" from chan_dahdi.conf
961
	 */
961
	 */
962
	unsigned int mwimonitor_fsk:1;
962
	unsigned int mwimonitor_fsk:1;
963
	/*!
963
	/*!
964
	 * \brief TRUE if the FXO port monitors for rpas precursor to fsk MWI indications from the other end.
964
	 * \brief TRUE if the FXO port monitors for rpas precursor to fsk MWI indications from the other end.
965
	 * \note RPAS - Ring Pulse Alert Signal
965
	 * \note RPAS - Ring Pulse Alert Signal
966
	 * \note Set if the "mwimonitor" value read in contains "rpas" from chan_dahdi.conf
966
	 * \note Set if the "mwimonitor" value read in contains "rpas" from chan_dahdi.conf
967
	 */
967
	 */
968
	unsigned int mwimonitor_rpas:1;
968
	unsigned int mwimonitor_rpas:1;
969
	/*! \brief TRUE if an MWI monitor thread is currently active */
969
	/*! \brief TRUE if an MWI monitor thread is currently active */
970
	unsigned int mwimonitoractive:1;
970
	unsigned int mwimonitoractive:1;
971
	/*! \brief TRUE if a MWI message sending thread is active */
971
	/*! \brief TRUE if a MWI message sending thread is active */
972
	unsigned int mwisendactive:1;
972
	unsigned int mwisendactive:1;
973
	/*!
973
	/*!
974
	 * \brief TRUE if channel is out of reset and ready
974
	 * \brief TRUE if channel is out of reset and ready
975
	 * \note Set but not used.
975
	 * \note Set but not used.
976
	 */
976
	 */
977
	unsigned int inservice:1;
977
	unsigned int inservice:1;
978
	/*!
978
	/*!
979
	 * \brief TRUE if the channel is locally blocked.
979
	 * \brief TRUE if the channel is locally blocked.
980
	 * \note Applies to SS7 and MFCR2 channels.
980
	 * \note Applies to SS7 and MFCR2 channels.
981
	 */
981
	 */
982
	unsigned int locallyblocked:1;
982
	unsigned int locallyblocked:1;
983
	/*!
983
	/*!
984
	 * \brief TRUE if the channel is remotely blocked.
984
	 * \brief TRUE if the channel is remotely blocked.
985
	 * \note Applies to SS7 and MFCR2 channels.
985
	 * \note Applies to SS7 and MFCR2 channels.
986
	 */
986
	 */
987
	unsigned int remotelyblocked:1;
987
	unsigned int remotelyblocked:1;
988
	/*!
988
	/*!
989
	 * \brief TRUE if the channel alarms will be managed also as Span ones
989
	 * \brief TRUE if the channel alarms will be managed also as Span ones
990
	 * \note Applies to all channels
990
	 * \note Applies to all channels
991
	 */
991
	 */
992
	unsigned int manages_span_alarms:1;
992
	unsigned int manages_span_alarms:1;
993

    
   
993

   
994
#if defined(HAVE_PRI)
994
#if defined(HAVE_PRI)
995
	struct sig_pri_span *pri;
995
	struct sig_pri_span *pri;
996
	int logicalspan;
996
	int logicalspan;
997
#endif
997
#endif
998
	/*!
998
	/*!
999
	 * \brief TRUE if SMDI (Simplified Message Desk Interface) is enabled
999
	 * \brief TRUE if SMDI (Simplified Message Desk Interface) is enabled
1000
	 * \note Set from the "usesmdi" value read in from chan_dahdi.conf
1000
	 * \note Set from the "usesmdi" value read in from chan_dahdi.conf
1001
	 */
1001
	 */
1002
	unsigned int use_smdi:1;
1002
	unsigned int use_smdi:1;
1003
	struct mwisend_info mwisend_data;
1003
	struct mwisend_info mwisend_data;
1004
	/*! \brief The SMDI interface to get SMDI messages from. */
1004
	/*! \brief The SMDI interface to get SMDI messages from. */
1005
	struct ast_smdi_interface *smdi_iface;
1005
	struct ast_smdi_interface *smdi_iface;
1006

    
   
1006

   
1007
	/*! \brief Distinctive Ring data */
1007
	/*! \brief Distinctive Ring data */
1008
	struct dahdi_distRings drings;
1008
	struct dahdi_distRings drings;
1009

    
   
1009

   
1010
	/*!
1010
	/*!
1011
	 * \brief The configured context for incoming calls.
1011
	 * \brief The configured context for incoming calls.
1012
	 * \note The "context" string read in from chan_dahdi.conf
1012
	 * \note The "context" string read in from chan_dahdi.conf
1013
	 */
1013
	 */
1014
	char context[AST_MAX_CONTEXT];
1014
	char context[AST_MAX_CONTEXT];
1015
	/*! 
1015
	/*! 
1016
	 * \brief A description for the channel configuration
1016
	 * \brief A description for the channel configuration
1017
	 * \note The "description" string read in from chan_dahdi.conf
1017
	 * \note The "description" string read in from chan_dahdi.conf
1018
	 */
1018
	 */
1019
	char description[32];
1019
	char description[32];
1020
	/*!
1020
	/*!
1021
	 * \brief Saved context string.
1021
	 * \brief Saved context string.
1022
	 */
1022
	 */
1023
	char defcontext[AST_MAX_CONTEXT];
1023
	char defcontext[AST_MAX_CONTEXT];
1024
	/*! \brief Extension to use in the dialplan. */
1024
	/*! \brief Extension to use in the dialplan. */
1025
	char exten[AST_MAX_EXTENSION];
1025
	char exten[AST_MAX_EXTENSION];
1026
	/*!
1026
	/*!
1027
	 * \brief Language configured for calls.
1027
	 * \brief Language configured for calls.
1028
	 * \note The "language" string read in from chan_dahdi.conf
1028
	 * \note The "language" string read in from chan_dahdi.conf
1029
	 */
1029
	 */
1030
	char language[MAX_LANGUAGE];
1030
	char language[MAX_LANGUAGE];
1031
	/*!
1031
	/*!
1032
	 * \brief The configured music-on-hold class to use for calls.
1032
	 * \brief The configured music-on-hold class to use for calls.
1033
	 * \note The "musicclass" or "mohinterpret" or "musiconhold" string read in from chan_dahdi.conf
1033
	 * \note The "musicclass" or "mohinterpret" or "musiconhold" string read in from chan_dahdi.conf
1034
	 */
1034
	 */
1035
	char mohinterpret[MAX_MUSICCLASS];
1035
	char mohinterpret[MAX_MUSICCLASS];
1036
	/*!
1036
	/*!
1037
	 * \brief Suggested music-on-hold class for peer channel to use for calls.
1037
	 * \brief Suggested music-on-hold class for peer channel to use for calls.
1038
	 * \note The "mohsuggest" string read in from chan_dahdi.conf
1038
	 * \note The "mohsuggest" string read in from chan_dahdi.conf
1039
	 */
1039
	 */
1040
	char mohsuggest[MAX_MUSICCLASS];
1040
	char mohsuggest[MAX_MUSICCLASS];
1041
	char parkinglot[AST_MAX_EXTENSION]; /*!< Parking lot for this channel */
1041
	char parkinglot[AST_MAX_EXTENSION]; /*!< Parking lot for this channel */
1042
#if defined(HAVE_PRI) || defined(HAVE_SS7)
1042
#if defined(HAVE_PRI) || defined(HAVE_SS7)
1043
	/*! \brief Automatic Number Identification number (Alternate PRI caller ID number) */
1043
	/*! \brief Automatic Number Identification number (Alternate PRI caller ID number) */
1044
	char cid_ani[AST_MAX_EXTENSION];
1044
	char cid_ani[AST_MAX_EXTENSION];
1045
#endif	/* defined(HAVE_PRI) || defined(HAVE_SS7) */
1045
#endif	/* defined(HAVE_PRI) || defined(HAVE_SS7) */
1046
	/*! \brief Automatic Number Identification code from PRI */
1046
	/*! \brief Automatic Number Identification code from PRI */
1047
	int cid_ani2;
1047
	int cid_ani2;
1048
	/*! \brief Caller ID number from an incoming call. */
1048
	/*! \brief Caller ID number from an incoming call. */
1049
	char cid_num[AST_MAX_EXTENSION];
1049
	char cid_num[AST_MAX_EXTENSION];
1050
	/*!
1050
	/*!
1051
	 * \brief Caller ID tag from incoming call
1051
	 * \brief Caller ID tag from incoming call
1052
	 * \note the "cid_tag" string read in from chan_dahdi.conf
1052
	 * \note the "cid_tag" string read in from chan_dahdi.conf
1053
	 */
1053
	 */
1054
	char cid_tag[AST_MAX_EXTENSION];
1054
	char cid_tag[AST_MAX_EXTENSION];
1055
	/*! \brief Caller ID Q.931 TON/NPI field values.  Set by PRI. Zero otherwise. */
1055
	/*! \brief Caller ID Q.931 TON/NPI field values.  Set by PRI. Zero otherwise. */
1056
	int cid_ton;
1056
	int cid_ton;
1057
	/*! \brief Caller ID name from an incoming call. */
1057
	/*! \brief Caller ID name from an incoming call. */
1058
	char cid_name[AST_MAX_EXTENSION];
1058
	char cid_name[AST_MAX_EXTENSION];
1059
	/*! \brief Caller ID subaddress from an incoming call. */
1059
	/*! \brief Caller ID subaddress from an incoming call. */
1060
	char cid_subaddr[AST_MAX_EXTENSION];
1060
	char cid_subaddr[AST_MAX_EXTENSION];
1061
	char *origcid_num;				/*!< malloced original callerid */
1061
	char *origcid_num;				/*!< malloced original callerid */
1062
	char *origcid_name;				/*!< malloced original callerid */
1062
	char *origcid_name;				/*!< malloced original callerid */
1063
	/*! \brief Call waiting number. */
1063
	/*! \brief Call waiting number. */
1064
	char callwait_num[AST_MAX_EXTENSION];
1064
	char callwait_num[AST_MAX_EXTENSION];
1065
	/*! \brief Call waiting name. */
1065
	/*! \brief Call waiting name. */
1066
	char callwait_name[AST_MAX_EXTENSION];
1066
	char callwait_name[AST_MAX_EXTENSION];
1067
	/*! \brief Redirecting Directory Number Information Service (RDNIS) number */
1067
	/*! \brief Redirecting Directory Number Information Service (RDNIS) number */
1068
	char rdnis[AST_MAX_EXTENSION];
1068
	char rdnis[AST_MAX_EXTENSION];
1069
	/*! \brief Dialed Number Identifier */
1069
	/*! \brief Dialed Number Identifier */
1070
	char dnid[AST_MAX_EXTENSION];
1070
	char dnid[AST_MAX_EXTENSION];
1071
	/*!
1071
	/*!
1072
	 * \brief Bitmapped groups this belongs to.
1072
	 * \brief Bitmapped groups this belongs to.
1073
	 * \note The "group" bitmapped group string read in from chan_dahdi.conf
1073
	 * \note The "group" bitmapped group string read in from chan_dahdi.conf
1074
	 */
1074
	 */
1075
	ast_group_t group;
1075
	ast_group_t group;
1076
	/*! \brief Default call PCM encoding format: DAHDI_LAW_ALAW or DAHDI_LAW_MULAW. */
1076
	/*! \brief Default call PCM encoding format: DAHDI_LAW_ALAW or DAHDI_LAW_MULAW. */
1077
	int law_default;
1077
	int law_default;
1078
	/*! \brief Active PCM encoding format: DAHDI_LAW_ALAW or DAHDI_LAW_MULAW */
1078
	/*! \brief Active PCM encoding format: DAHDI_LAW_ALAW or DAHDI_LAW_MULAW */
1079
	int law;
1079
	int law;
1080
	int confno;					/*!< Our conference */
1080
	int confno;					/*!< Our conference */
1081
	int confusers;					/*!< Who is using our conference */
1081
	int confusers;					/*!< Who is using our conference */
1082
	int propconfno;					/*!< Propagated conference number */
1082
	int propconfno;					/*!< Propagated conference number */
1083
	/*!
1083
	/*!
1084
	 * \brief Bitmapped call groups this belongs to.
1084
	 * \brief Bitmapped call groups this belongs to.
1085
	 * \note The "callgroup" bitmapped group string read in from chan_dahdi.conf
1085
	 * \note The "callgroup" bitmapped group string read in from chan_dahdi.conf
1086
	 */
1086
	 */
1087
	ast_group_t callgroup;
1087
	ast_group_t callgroup;
1088
	/*!
1088
	/*!
1089
	 * \brief Bitmapped pickup groups this belongs to.
1089
	 * \brief Bitmapped pickup groups this belongs to.
1090
	 * \note The "pickupgroup" bitmapped group string read in from chan_dahdi.conf
1090
	 * \note The "pickupgroup" bitmapped group string read in from chan_dahdi.conf
1091
	 */
1091
	 */
1092
	ast_group_t pickupgroup;
1092
	ast_group_t pickupgroup;
1093
	/*!
1093
	/*!
1094
	 * \brief Channel variable list with associated values to set when a channel is created.
1094
	 * \brief Channel variable list with associated values to set when a channel is created.
1095
	 * \note The "setvar" strings read in from chan_dahdi.conf
1095
	 * \note The "setvar" strings read in from chan_dahdi.conf
1096
	 */
1096
	 */
1097
	struct ast_variable *vars;
1097
	struct ast_variable *vars;
1098
	int channel;					/*!< Channel Number */
1098
	int channel;					/*!< Channel Number */
1099
	int span;					/*!< Span number */
1099
	int span;					/*!< Span number */
1100
	time_t guardtime;				/*!< Must wait this much time before using for new call */
1100
	time_t guardtime;				/*!< Must wait this much time before using for new call */
1101
	int cid_signalling;				/*!< CID signalling type bell202 or v23 */
1101
	int cid_signalling;				/*!< CID signalling type bell202 or v23 */
1102
	int cid_start;					/*!< CID start indicator, polarity or ring or DTMF without warning event */
1102
	int cid_start;					/*!< CID start indicator, polarity or ring or DTMF without warning event */
1103
	int dtmfcid_holdoff_state;		/*!< State indicator that allows for line to settle before checking for dtmf energy */
1103
	int dtmfcid_holdoff_state;		/*!< State indicator that allows for line to settle before checking for dtmf energy */
1104
	struct timeval	dtmfcid_delay;  /*!< Time value used for allow line to settle */
1104
	struct timeval	dtmfcid_delay;  /*!< Time value used for allow line to settle */
1105
	int callingpres;				/*!< The value of calling presentation that we're going to use when placing a PRI call */
1105
	int callingpres;				/*!< The value of calling presentation that we're going to use when placing a PRI call */
1106
	int callwaitingrepeat;				/*!< How many samples to wait before repeating call waiting */
1106
	int callwaitingrepeat;				/*!< How many samples to wait before repeating call waiting */
1107
	int cidcwexpire;				/*!< When to stop waiting for CID/CW CAS response (In samples) */
1107
	int cidcwexpire;				/*!< When to stop waiting for CID/CW CAS response (In samples) */
1108
	int cid_suppress_expire;		/*!< How many samples to suppress after a CID spill. */
1108
	int cid_suppress_expire;		/*!< How many samples to suppress after a CID spill. */
1109
	/*! \brief Analog caller ID waveform sample buffer */
1109
	/*! \brief Analog caller ID waveform sample buffer */
1110
	unsigned char *cidspill;
1110
	unsigned char *cidspill;
1111
	/*! \brief Position in the cidspill buffer to send out next. */
1111
	/*! \brief Position in the cidspill buffer to send out next. */
1112
	int cidpos;
1112
	int cidpos;
1113
	/*! \brief Length of the cidspill buffer containing samples. */
1113
	/*! \brief Length of the cidspill buffer containing samples. */
1114
	int cidlen;
1114
	int cidlen;
1115
	/*! \brief Ring timeout timer?? */
1115
	/*! \brief Ring timeout timer?? */
1116
	int ringt;
1116
	int ringt;
1117
	/*!
1117
	/*!
1118
	 * \brief Ring timeout base.
1118
	 * \brief Ring timeout base.
1119
	 * \note Value computed indirectly from "ringtimeout" read in from chan_dahdi.conf
1119
	 * \note Value computed indirectly from "ringtimeout" read in from chan_dahdi.conf
1120
	 */
1120
	 */
1121
	int ringt_base;
1121
	int ringt_base;
1122
	/*!
1122
	/*!
1123
	 * \brief Number of most significant digits/characters to strip from the dialed number.
1123
	 * \brief Number of most significant digits/characters to strip from the dialed number.
1124
	 * \note Feature is deprecated.  Use dialplan logic.
1124
	 * \note Feature is deprecated.  Use dialplan logic.
1125
	 * \note The characters are stripped before the PRI TON/NPI prefix
1125
	 * \note The characters are stripped before the PRI TON/NPI prefix
1126
	 * characters are processed.
1126
	 * characters are processed.
1127
	 */
1127
	 */
1128
	int stripmsd;
1128
	int stripmsd;
1129
	/*!
1129
	/*!
1130
	 * \brief TRUE if Call Waiting (CW) CPE Alert Signal (CAS) is being sent.
1130
	 * \brief TRUE if Call Waiting (CW) CPE Alert Signal (CAS) is being sent.
1131
	 * \note
1131
	 * \note
1132
	 * After CAS is sent, the call waiting caller id will be sent if the phone
1132
	 * After CAS is sent, the call waiting caller id will be sent if the phone
1133
	 * gives a positive reply.
1133
	 * gives a positive reply.
1134
	 */
1134
	 */
1135
	int callwaitcas;
1135
	int callwaitcas;
1136
	/*! \brief Number of call waiting rings. */
1136
	/*! \brief Number of call waiting rings. */
1137
	int callwaitrings;
1137
	int callwaitrings;
1138
	/*! \brief Echo cancel parameters. */
1138
	/*! \brief Echo cancel parameters. */
1139
	struct {
1139
	struct {
1140
		struct dahdi_echocanparams head;
1140
		struct dahdi_echocanparams head;
1141
		struct dahdi_echocanparam params[DAHDI_MAX_ECHOCANPARAMS];
1141
		struct dahdi_echocanparam params[DAHDI_MAX_ECHOCANPARAMS];
1142
	} echocancel;
1142
	} echocancel;
1143
	/*!
1143
	/*!
1144
	 * \brief Echo training time. 0 = disabled
1144
	 * \brief Echo training time. 0 = disabled
1145
	 * \note Set from the "echotraining" value read in from chan_dahdi.conf
1145
	 * \note Set from the "echotraining" value read in from chan_dahdi.conf
1146
	 */
1146
	 */
1147
	int echotraining;
1147
	int echotraining;
1148
	/*! \brief Filled with 'w'.  XXX Purpose?? */
1148
	/*! \brief Filled with 'w'.  XXX Purpose?? */
1149
	char echorest[20];
1149
	char echorest[20];
1150
	/*!
1150
	/*!
1151
	 * \brief Number of times to see "busy" tone before hanging up.
1151
	 * \brief Number of times to see "busy" tone before hanging up.
1152
	 * \note Set from the "busycount" value read in from chan_dahdi.conf
1152
	 * \note Set from the "busycount" value read in from chan_dahdi.conf
1153
	 */
1153
	 */
1154
	int busycount;
1154
	int busycount;
1155
	/*!
1155
	/*!
1156
	 * \brief Busy cadence pattern description.
1156
	 * \brief Busy cadence pattern description.
1157
	 * \note Set from the "busypattern" value read from chan_dahdi.conf
1157
	 * \note Set from the "busypattern" value read from chan_dahdi.conf
1158
	 */
1158
	 */
1159
	struct ast_dsp_busy_pattern busy_cadence;
1159
	struct ast_dsp_busy_pattern busy_cadence;
1160
	/*!
1160
	/*!
1161
	 * \brief Bitmapped call progress detection flags. CALLPROGRESS_xxx values.
1161
	 * \brief Bitmapped call progress detection flags. CALLPROGRESS_xxx values.
1162
	 * \note Bits set from the "callprogress" and "faxdetect" values read in from chan_dahdi.conf
1162
	 * \note Bits set from the "callprogress" and "faxdetect" values read in from chan_dahdi.conf
1163
	 */
1163
	 */
1164
	int callprogress;
1164
	int callprogress;
1165
	/*!
1165
	/*!
1166
	 * \brief Number of milliseconds to wait for dialtone.
1166
	 * \brief Number of milliseconds to wait for dialtone.
1167
	 * \note Set from the "waitfordialtone" value read in from chan_dahdi.conf
1167
	 * \note Set from the "waitfordialtone" value read in from chan_dahdi.conf
1168
	 */
1168
	 */
1169
	int waitfordialtone;
1169
	int waitfordialtone;
1170
	struct timeval waitingfordt;			/*!< Time we started waiting for dialtone */
1170
	struct timeval waitingfordt;			/*!< Time we started waiting for dialtone */
1171
	struct timeval flashtime;			/*!< Last flash-hook time */
1171
	struct timeval flashtime;			/*!< Last flash-hook time */
1172
	/*! \brief Opaque DSP configuration structure. */
1172
	/*! \brief Opaque DSP configuration structure. */
1173
	struct ast_dsp *dsp;
1173
	struct ast_dsp *dsp;
1174
	/*! \brief DAHDI dial operation command struct for ioctl() call. */
1174
	/*! \brief DAHDI dial operation command struct for ioctl() call. */
1175
	struct dahdi_dialoperation dop;
1175
	struct dahdi_dialoperation dop;
1176
	int whichwink;					/*!< SIG_FEATDMF_TA Which wink are we on? */
1176
	int whichwink;					/*!< SIG_FEATDMF_TA Which wink are we on? */
1177
	/*! \brief Second part of SIG_FEATDMF_TA wink operation. */
1177
	/*! \brief Second part of SIG_FEATDMF_TA wink operation. */
1178
	char finaldial[64];
1178
	char finaldial[64];
1179
	char accountcode[AST_MAX_ACCOUNT_CODE];		/*!< Account code */
1179
	char accountcode[AST_MAX_ACCOUNT_CODE];		/*!< Account code */
1180
	int amaflags;					/*!< AMA Flags */
1180
	int amaflags;					/*!< AMA Flags */
1181
	struct tdd_state *tdd;				/*!< TDD flag */
1181
	struct tdd_state *tdd;				/*!< TDD flag */
1182
	/*! \brief Accumulated call forwarding number. */
1182
	/*! \brief Accumulated call forwarding number. */
1183
	char call_forward[AST_MAX_EXTENSION];
1183
	char call_forward[AST_MAX_EXTENSION];
1184
	/*!
1184
	/*!
1185
	 * \brief Voice mailbox location.
1185
	 * \brief Voice mailbox location.
1186
	 * \note Set from the "mailbox" string read in from chan_dahdi.conf
1186
	 * \note Set from the "mailbox" string read in from chan_dahdi.conf
1187
	 */
1187
	 */
1188
	char mailbox[AST_MAX_EXTENSION];
1188
	char mailbox[AST_MAX_EXTENSION];
1189
	/*! \brief Opaque event subscription parameters for message waiting indication support. */
1189
	/*! \brief Opaque event subscription parameters for message waiting indication support. */
1190
	struct ast_event_sub *mwi_event_sub;
1190
	struct ast_event_sub *mwi_event_sub;
1191
	/*! \brief Delayed dialing for E911.  Overlap digits for ISDN. */
1191
	/*! \brief Delayed dialing for E911.  Overlap digits for ISDN. */
1192
	char dialdest[256];
1192
	char dialdest[256];
1193
#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
1193
#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
1194
	struct dahdi_vmwi_info mwisend_setting;				/*!< Which VMWI methods to use */
1194
	struct dahdi_vmwi_info mwisend_setting;				/*!< Which VMWI methods to use */
1195
	unsigned int mwisend_fsk: 1;		/*! Variable for enabling FSK MWI handling in chan_dahdi */
1195
	unsigned int mwisend_fsk: 1;		/*! Variable for enabling FSK MWI handling in chan_dahdi */
1196
	unsigned int mwisend_rpas:1;		/*! Variable for enabling Ring Pulse Alert before MWI FSK Spill */
1196
	unsigned int mwisend_rpas:1;		/*! Variable for enabling Ring Pulse Alert before MWI FSK Spill */
1197
#endif
1197
#endif
1198
	int distinctivering;				/*!< Which distinctivering to use */
1198
	int distinctivering;				/*!< Which distinctivering to use */
1199
	int dtmfrelax;					/*!< whether to run in relaxed DTMF mode */
1199
	int dtmfrelax;					/*!< whether to run in relaxed DTMF mode */
1200
	/*! \brief Holding place for event injected from outside normal operation. */
1200
	/*! \brief Holding place for event injected from outside normal operation. */
1201
	int fake_event;
1201
	int fake_event;
1202
	/*!
1202
	/*!
1203
	 * \brief Minimal time period (ms) between the answer polarity
1203
	 * \brief Minimal time period (ms) between the answer polarity
1204
	 * switch and hangup polarity switch.
1204
	 * switch and hangup polarity switch.
1205
	 */
1205
	 */
1206
	int polarityonanswerdelay;
1206
	int polarityonanswerdelay;
1207
	/*! \brief Start delay time if polarityonanswerdelay is nonzero. */
1207
	/*! \brief Start delay time if polarityonanswerdelay is nonzero. */
1208
	struct timeval polaritydelaytv;
1208
	struct timeval polaritydelaytv;
1209
	/*!
1209
	/*!
1210
	 * \brief Send caller ID on FXS after this many rings. Set to 1 for US.
1210
	 * \brief Send caller ID on FXS after this many rings. Set to 1 for US.
1211
	 * \note Set from the "sendcalleridafter" value read in from chan_dahdi.conf
1211
	 * \note Set from the "sendcalleridafter" value read in from chan_dahdi.conf
1212
	 */
1212
	 */
1213
	int sendcalleridafter;
1213
	int sendcalleridafter;
1214
	/*! \brief Current line interface polarity. POLARITY_IDLE, POLARITY_REV */
1214
	/*! \brief Current line interface polarity. POLARITY_IDLE, POLARITY_REV */
1215
	int polarity;
1215
	int polarity;
1216
	/*! \brief DSP feature flags: DSP_FEATURE_xxx */
1216
	/*! \brief DSP feature flags: DSP_FEATURE_xxx */
1217
	int dsp_features;
1217
	int dsp_features;
1218
#if defined(HAVE_SS7)
1218
#if defined(HAVE_SS7)
1219
	/*! \brief SS7 control parameters */
1219
	/*! \brief SS7 control parameters */
1220
	struct sig_ss7_linkset *ss7;
1220
	struct sig_ss7_linkset *ss7;
1221
#endif	/* defined(HAVE_SS7) */
1221
#endif	/* defined(HAVE_SS7) */
1222
#ifdef HAVE_OPENR2
1222
#ifdef HAVE_OPENR2
1223
	struct dahdi_mfcr2 *mfcr2;
1223
	struct dahdi_mfcr2 *mfcr2;
1224
	openr2_chan_t *r2chan;
1224
	openr2_chan_t *r2chan;
1225
	openr2_calling_party_category_t mfcr2_recvd_category;
1225
	openr2_calling_party_category_t mfcr2_recvd_category;
1226
	openr2_calling_party_category_t mfcr2_category;
1226
	openr2_calling_party_category_t mfcr2_category;
1227
	int mfcr2_dnis_index;
1227
	int mfcr2_dnis_index;
1228
	int mfcr2_ani_index;
1228
	int mfcr2_ani_index;
1229
	int mfcr2call:1;
1229
	int mfcr2call:1;
1230
	int mfcr2_answer_pending:1;
1230
	int mfcr2_answer_pending:1;
1231
	int mfcr2_charge_calls:1;
1231
	int mfcr2_charge_calls:1;
1232
	int mfcr2_allow_collect_calls:1;
1232
	int mfcr2_allow_collect_calls:1;
1233
	int mfcr2_forced_release:1;
1233
	int mfcr2_forced_release:1;
1234
	int mfcr2_dnis_matched:1;
1234
	int mfcr2_dnis_matched:1;
1235
	int mfcr2_call_accepted:1;
1235
	int mfcr2_call_accepted:1;
1236
	int mfcr2_accept_on_offer:1;
1236
	int mfcr2_accept_on_offer:1;
1237
	int mfcr2_progress_sent:1;
1237
	int mfcr2_progress_sent:1;
1238
#endif
1238
#endif
1239
	/*! \brief DTMF digit in progress.  0 when no digit in progress. */
1239
	/*! \brief DTMF digit in progress.  0 when no digit in progress. */
1240
	char begindigit;
1240
	char begindigit;
1241
	/*! \brief TRUE if confrence is muted. */
1241
	/*! \brief TRUE if confrence is muted. */
1242
	int muting;
1242
	int muting;
1243
	void *sig_pvt;
1243
	void *sig_pvt;
1244
	struct ast_cc_config_params *cc_params;
1244
	struct ast_cc_config_params *cc_params;
1245
	/* DAHDI channel names may differ greatly from the
1245
	/* DAHDI channel names may differ greatly from the
1246
	 * string that was provided to an app such as Dial. We
1246
	 * string that was provided to an app such as Dial. We
1247
	 * need to save the original string passed to dahdi_request
1247
	 * need to save the original string passed to dahdi_request
1248
	 * for call completion purposes. This way, we can replicate
1248
	 * for call completion purposes. This way, we can replicate
1249
	 * the original dialed string later.
1249
	 * the original dialed string later.
1250
	 */
1250
	 */
1251
	char dialstring[AST_CHANNEL_NAME];
1251
	char dialstring[AST_CHANNEL_NAME];
1252
};
1252
};
1253

    
   
1253

   
1254
#define DATA_EXPORT_DAHDI_PVT(MEMBER)					\
1254
#define DATA_EXPORT_DAHDI_PVT(MEMBER)					\
1255
	MEMBER(dahdi_pvt, cid_rxgain, AST_DATA_DOUBLE)			\
1255
	MEMBER(dahdi_pvt, cid_rxgain, AST_DATA_DOUBLE)			\
1256
	MEMBER(dahdi_pvt, rxgain, AST_DATA_DOUBLE)			\
1256
	MEMBER(dahdi_pvt, rxgain, AST_DATA_DOUBLE)			\
1257
	MEMBER(dahdi_pvt, txgain, AST_DATA_DOUBLE)			\
1257
	MEMBER(dahdi_pvt, txgain, AST_DATA_DOUBLE)			\
1258
	MEMBER(dahdi_pvt, txdrc, AST_DATA_DOUBLE)			\
1258
	MEMBER(dahdi_pvt, txdrc, AST_DATA_DOUBLE)			\
1259
	MEMBER(dahdi_pvt, rxdrc, AST_DATA_DOUBLE)			\
1259
	MEMBER(dahdi_pvt, rxdrc, AST_DATA_DOUBLE)			\
1260
	MEMBER(dahdi_pvt, adsi, AST_DATA_BOOLEAN)			\
1260
	MEMBER(dahdi_pvt, adsi, AST_DATA_BOOLEAN)			\
1261
	MEMBER(dahdi_pvt, answeronpolarityswitch, AST_DATA_BOOLEAN)	\
1261
	MEMBER(dahdi_pvt, answeronpolarityswitch, AST_DATA_BOOLEAN)	\
1262
	MEMBER(dahdi_pvt, busydetect, AST_DATA_BOOLEAN)			\
1262
	MEMBER(dahdi_pvt, busydetect, AST_DATA_BOOLEAN)			\
1263
	MEMBER(dahdi_pvt, callreturn, AST_DATA_BOOLEAN)			\
1263
	MEMBER(dahdi_pvt, callreturn, AST_DATA_BOOLEAN)			\
1264
	MEMBER(dahdi_pvt, callwaiting, AST_DATA_BOOLEAN)		\
1264
	MEMBER(dahdi_pvt, callwaiting, AST_DATA_BOOLEAN)		\
1265
	MEMBER(dahdi_pvt, callwaitingcallerid, AST_DATA_BOOLEAN)	\
1265
	MEMBER(dahdi_pvt, callwaitingcallerid, AST_DATA_BOOLEAN)	\
1266
	MEMBER(dahdi_pvt, cancallforward, AST_DATA_BOOLEAN)		\
1266
	MEMBER(dahdi_pvt, cancallforward, AST_DATA_BOOLEAN)		\
1267
	MEMBER(dahdi_pvt, canpark, AST_DATA_BOOLEAN)			\
1267
	MEMBER(dahdi_pvt, canpark, AST_DATA_BOOLEAN)			\
1268
	MEMBER(dahdi_pvt, confirmanswer, AST_DATA_BOOLEAN)		\
1268
	MEMBER(dahdi_pvt, confirmanswer, AST_DATA_BOOLEAN)		\
1269
	MEMBER(dahdi_pvt, destroy, AST_DATA_BOOLEAN)			\
1269
	MEMBER(dahdi_pvt, destroy, AST_DATA_BOOLEAN)			\
1270
	MEMBER(dahdi_pvt, didtdd, AST_DATA_BOOLEAN)			\
1270
	MEMBER(dahdi_pvt, didtdd, AST_DATA_BOOLEAN)			\
1271
	MEMBER(dahdi_pvt, dialednone, AST_DATA_BOOLEAN)			\
1271
	MEMBER(dahdi_pvt, dialednone, AST_DATA_BOOLEAN)			\
1272
	MEMBER(dahdi_pvt, dialing, AST_DATA_BOOLEAN)			\
1272
	MEMBER(dahdi_pvt, dialing, AST_DATA_BOOLEAN)			\
1273
	MEMBER(dahdi_pvt, digital, AST_DATA_BOOLEAN)			\
1273
	MEMBER(dahdi_pvt, digital, AST_DATA_BOOLEAN)			\
1274
	MEMBER(dahdi_pvt, dnd, AST_DATA_BOOLEAN)			\
1274
	MEMBER(dahdi_pvt, dnd, AST_DATA_BOOLEAN)			\
1275
	MEMBER(dahdi_pvt, echobreak, AST_DATA_BOOLEAN)			\
1275
	MEMBER(dahdi_pvt, echobreak, AST_DATA_BOOLEAN)			\
1276
	MEMBER(dahdi_pvt, echocanbridged, AST_DATA_BOOLEAN)		\
1276
	MEMBER(dahdi_pvt, echocanbridged, AST_DATA_BOOLEAN)		\
1277
	MEMBER(dahdi_pvt, echocanon, AST_DATA_BOOLEAN)			\
1277
	MEMBER(dahdi_pvt, echocanon, AST_DATA_BOOLEAN)			\
1278
	MEMBER(dahdi_pvt, faxhandled, AST_DATA_BOOLEAN)			\
1278
	MEMBER(dahdi_pvt, faxhandled, AST_DATA_BOOLEAN)			\
1279
	MEMBER(dahdi_pvt, usefaxbuffers, AST_DATA_BOOLEAN)		\
1279
	MEMBER(dahdi_pvt, usefaxbuffers, AST_DATA_BOOLEAN)		\
1280
	MEMBER(dahdi_pvt, bufferoverrideinuse, AST_DATA_BOOLEAN)	\
1280
	MEMBER(dahdi_pvt, bufferoverrideinuse, AST_DATA_BOOLEAN)	\
1281
	MEMBER(dahdi_pvt, firstradio, AST_DATA_BOOLEAN)			\
1281
	MEMBER(dahdi_pvt, firstradio, AST_DATA_BOOLEAN)			\
1282
	MEMBER(dahdi_pvt, hanguponpolarityswitch, AST_DATA_BOOLEAN)	\
1282
	MEMBER(dahdi_pvt, hanguponpolarityswitch, AST_DATA_BOOLEAN)	\
1283
	MEMBER(dahdi_pvt, hardwaredtmf, AST_DATA_BOOLEAN)		\
1283
	MEMBER(dahdi_pvt, hardwaredtmf, AST_DATA_BOOLEAN)		\
1284
	MEMBER(dahdi_pvt, hidecallerid, AST_DATA_BOOLEAN)		\
1284
	MEMBER(dahdi_pvt, hidecallerid, AST_DATA_BOOLEAN)		\
1285
	MEMBER(dahdi_pvt, hidecalleridname, AST_DATA_BOOLEAN)		\
1285
	MEMBER(dahdi_pvt, hidecalleridname, AST_DATA_BOOLEAN)		\
1286
	MEMBER(dahdi_pvt, ignoredtmf, AST_DATA_BOOLEAN)			\
1286
	MEMBER(dahdi_pvt, ignoredtmf, AST_DATA_BOOLEAN)			\
1287
	MEMBER(dahdi_pvt, immediate, AST_DATA_BOOLEAN)			\
1287
	MEMBER(dahdi_pvt, immediate, AST_DATA_BOOLEAN)			\
1288
	MEMBER(dahdi_pvt, inalarm, AST_DATA_BOOLEAN)			\
1288
	MEMBER(dahdi_pvt, inalarm, AST_DATA_BOOLEAN)			\
1289
	MEMBER(dahdi_pvt, mate, AST_DATA_BOOLEAN)			\
1289
	MEMBER(dahdi_pvt, mate, AST_DATA_BOOLEAN)			\
1290
	MEMBER(dahdi_pvt, outgoing, AST_DATA_BOOLEAN)			\
1290
	MEMBER(dahdi_pvt, outgoing, AST_DATA_BOOLEAN)			\
1291
	MEMBER(dahdi_pvt, permcallwaiting, AST_DATA_BOOLEAN)		\
1291
	MEMBER(dahdi_pvt, permcallwaiting, AST_DATA_BOOLEAN)		\
1292
	MEMBER(dahdi_pvt, priindication_oob, AST_DATA_BOOLEAN)		\
1292
	MEMBER(dahdi_pvt, priindication_oob, AST_DATA_BOOLEAN)		\
1293
	MEMBER(dahdi_pvt, priexclusive, AST_DATA_BOOLEAN)		\
1293
	MEMBER(dahdi_pvt, priexclusive, AST_DATA_BOOLEAN)		\
1294
	MEMBER(dahdi_pvt, pulse, AST_DATA_BOOLEAN)			\
1294
	MEMBER(dahdi_pvt, pulse, AST_DATA_BOOLEAN)			\
1295
	MEMBER(dahdi_pvt, pulsedial, AST_DATA_BOOLEAN)			\
1295
	MEMBER(dahdi_pvt, pulsedial, AST_DATA_BOOLEAN)			\
1296
	MEMBER(dahdi_pvt, restartpending, AST_DATA_BOOLEAN)		\
1296
	MEMBER(dahdi_pvt, restartpending, AST_DATA_BOOLEAN)		\
1297
	MEMBER(dahdi_pvt, restrictcid, AST_DATA_BOOLEAN)		\
1297
	MEMBER(dahdi_pvt, restrictcid, AST_DATA_BOOLEAN)		\
1298
	MEMBER(dahdi_pvt, threewaycalling, AST_DATA_BOOLEAN)		\
1298
	MEMBER(dahdi_pvt, threewaycalling, AST_DATA_BOOLEAN)		\
1299
	MEMBER(dahdi_pvt, transfer, AST_DATA_BOOLEAN)			\
1299
	MEMBER(dahdi_pvt, transfer, AST_DATA_BOOLEAN)			\
1300
	MEMBER(dahdi_pvt, use_callerid, AST_DATA_BOOLEAN)		\
1300
	MEMBER(dahdi_pvt, use_callerid, AST_DATA_BOOLEAN)		\
1301
	MEMBER(dahdi_pvt, use_callingpres, AST_DATA_BOOLEAN)		\
1301
	MEMBER(dahdi_pvt, use_callingpres, AST_DATA_BOOLEAN)		\
1302
	MEMBER(dahdi_pvt, usedistinctiveringdetection, AST_DATA_BOOLEAN)	\
1302
	MEMBER(dahdi_pvt, usedistinctiveringdetection, AST_DATA_BOOLEAN)	\
1303
	MEMBER(dahdi_pvt, dahditrcallerid, AST_DATA_BOOLEAN)			\
1303
	MEMBER(dahdi_pvt, dahditrcallerid, AST_DATA_BOOLEAN)			\
1304
	MEMBER(dahdi_pvt, transfertobusy, AST_DATA_BOOLEAN)			\
1304
	MEMBER(dahdi_pvt, transfertobusy, AST_DATA_BOOLEAN)			\
1305
	MEMBER(dahdi_pvt, mwimonitor_neon, AST_DATA_BOOLEAN)			\
1305
	MEMBER(dahdi_pvt, mwimonitor_neon, AST_DATA_BOOLEAN)			\
1306
	MEMBER(dahdi_pvt, mwimonitor_fsk, AST_DATA_BOOLEAN)			\
1306
	MEMBER(dahdi_pvt, mwimonitor_fsk, AST_DATA_BOOLEAN)			\
1307
	MEMBER(dahdi_pvt, mwimonitor_rpas, AST_DATA_BOOLEAN)			\
1307
	MEMBER(dahdi_pvt, mwimonitor_rpas, AST_DATA_BOOLEAN)			\
1308
	MEMBER(dahdi_pvt, mwimonitoractive, AST_DATA_BOOLEAN)			\
1308
	MEMBER(dahdi_pvt, mwimonitoractive, AST_DATA_BOOLEAN)			\
1309
	MEMBER(dahdi_pvt, mwisendactive, AST_DATA_BOOLEAN)			\
1309
	MEMBER(dahdi_pvt, mwisendactive, AST_DATA_BOOLEAN)			\
1310
	MEMBER(dahdi_pvt, inservice, AST_DATA_BOOLEAN)				\
1310
	MEMBER(dahdi_pvt, inservice, AST_DATA_BOOLEAN)				\
1311
	MEMBER(dahdi_pvt, locallyblocked, AST_DATA_BOOLEAN)			\
1311
	MEMBER(dahdi_pvt, locallyblocked, AST_DATA_BOOLEAN)			\
1312
	MEMBER(dahdi_pvt, remotelyblocked, AST_DATA_BOOLEAN)			\
1312
	MEMBER(dahdi_pvt, remotelyblocked, AST_DATA_BOOLEAN)			\
1313
	MEMBER(dahdi_pvt, manages_span_alarms, AST_DATA_BOOLEAN)		\
1313
	MEMBER(dahdi_pvt, manages_span_alarms, AST_DATA_BOOLEAN)		\
1314
	MEMBER(dahdi_pvt, use_smdi, AST_DATA_BOOLEAN)				\
1314
	MEMBER(dahdi_pvt, use_smdi, AST_DATA_BOOLEAN)				\
1315
	MEMBER(dahdi_pvt, context, AST_DATA_STRING)				\
1315
	MEMBER(dahdi_pvt, context, AST_DATA_STRING)				\
1316
	MEMBER(dahdi_pvt, defcontext, AST_DATA_STRING)				\
1316
	MEMBER(dahdi_pvt, defcontext, AST_DATA_STRING)				\
1317
	MEMBER(dahdi_pvt, description, AST_DATA_STRING)				\
1317
	MEMBER(dahdi_pvt, description, AST_DATA_STRING)				\
1318
	MEMBER(dahdi_pvt, exten, AST_DATA_STRING)				\
1318
	MEMBER(dahdi_pvt, exten, AST_DATA_STRING)				\
1319
	MEMBER(dahdi_pvt, language, AST_DATA_STRING)				\
1319
	MEMBER(dahdi_pvt, language, AST_DATA_STRING)				\
1320
	MEMBER(dahdi_pvt, mohinterpret, AST_DATA_STRING)			\
1320
	MEMBER(dahdi_pvt, mohinterpret, AST_DATA_STRING)			\
1321
	MEMBER(dahdi_pvt, mohsuggest, AST_DATA_STRING)				\
1321
	MEMBER(dahdi_pvt, mohsuggest, AST_DATA_STRING)				\
1322
	MEMBER(dahdi_pvt, parkinglot, AST_DATA_STRING)
1322
	MEMBER(dahdi_pvt, parkinglot, AST_DATA_STRING)
1323

    
   
1323

   
1324
AST_DATA_STRUCTURE(dahdi_pvt, DATA_EXPORT_DAHDI_PVT);
1324
AST_DATA_STRUCTURE(dahdi_pvt, DATA_EXPORT_DAHDI_PVT);
1325

    
   
1325

   
1326
static struct dahdi_pvt *iflist = NULL;	/*!< Main interface list start */
1326
static struct dahdi_pvt *iflist = NULL;	/*!< Main interface list start */
1327
static struct dahdi_pvt *ifend = NULL;	/*!< Main interface list end */
1327
static struct dahdi_pvt *ifend = NULL;	/*!< Main interface list end */
1328

    
   
1328

   
1329
#if defined(HAVE_PRI)
1329
#if defined(HAVE_PRI)
1330
static struct dahdi_parms_pseudo {
1330
static struct dahdi_parms_pseudo {
1331
	int buf_no;					/*!< Number of buffers */
1331
	int buf_no;					/*!< Number of buffers */
1332
	int buf_policy;				/*!< Buffer policy */
1332
	int buf_policy;				/*!< Buffer policy */
1333
	int faxbuf_no;              /*!< Number of Fax buffers */
1333
	int faxbuf_no;              /*!< Number of Fax buffers */
1334
	int faxbuf_policy;          /*!< Fax buffer policy */
1334
	int faxbuf_policy;          /*!< Fax buffer policy */
1335
} dahdi_pseudo_parms;
1335
} dahdi_pseudo_parms;
1336
#endif	/* defined(HAVE_PRI) */
1336
#endif	/* defined(HAVE_PRI) */
1337

    
   
1337

   
1338
/*! \brief Channel configuration from chan_dahdi.conf .
1338
/*! \brief Channel configuration from chan_dahdi.conf .
1339
 * This struct is used for parsing the [channels] section of chan_dahdi.conf.
1339
 * This struct is used for parsing the [channels] section of chan_dahdi.conf.
1340
 * Generally there is a field here for every possible configuration item.
1340
 * Generally there is a field here for every possible configuration item.
1341
 *
1341
 *
1342
 * The state of fields is saved along the parsing and whenever a 'channel'
1342
 * The state of fields is saved along the parsing and whenever a 'channel'
1343
 * statement is reached, the current dahdi_chan_conf is used to configure the
1343
 * statement is reached, the current dahdi_chan_conf is used to configure the
1344
 * channel (struct dahdi_pvt)
1344
 * channel (struct dahdi_pvt)
1345
 *
1345
 *
1346
 * \see dahdi_chan_init for the default values.
1346
 * \see dahdi_chan_init for the default values.
1347
 */
1347
 */
1348
struct dahdi_chan_conf {
1348
struct dahdi_chan_conf {
1349
	struct dahdi_pvt chan;
1349
	struct dahdi_pvt chan;
1350
#ifdef HAVE_PRI
1350
#ifdef HAVE_PRI
1351
	struct dahdi_pri pri;
1351
	struct dahdi_pri pri;
1352
#endif
1352
#endif
1353

    
   
1353

   
1354
#if defined(HAVE_SS7)
1354
#if defined(HAVE_SS7)
1355
	struct dahdi_ss7 ss7;
1355
	struct dahdi_ss7 ss7;
1356
#endif	/* defined(HAVE_SS7) */
1356
#endif	/* defined(HAVE_SS7) */
1357

    
   
1357

   
1358
#ifdef HAVE_OPENR2
1358
#ifdef HAVE_OPENR2
1359
	struct dahdi_mfcr2_conf mfcr2;
1359
	struct dahdi_mfcr2_conf mfcr2;
1360
#endif
1360
#endif
1361
	struct dahdi_params timing;
1361
	struct dahdi_params timing;
1362
	int is_sig_auto; /*!< Use channel signalling from DAHDI? */
1362
	int is_sig_auto; /*!< Use channel signalling from DAHDI? */
1363
	/*! Continue configuration even if a channel is not there. */
1363
	/*! Continue configuration even if a channel is not there. */
1364
	int ignore_failed_channels;
1364
	int ignore_failed_channels;
1365

    
   
1365

   
1366
	/*!
1366
	/*!
1367
	 * \brief The serial port to listen for SMDI data on
1367
	 * \brief The serial port to listen for SMDI data on
1368
	 * \note Set from the "smdiport" string read in from chan_dahdi.conf
1368
	 * \note Set from the "smdiport" string read in from chan_dahdi.conf
1369
	 */
1369
	 */
1370
	char smdi_port[SMDI_MAX_FILENAME_LEN];
1370
	char smdi_port[SMDI_MAX_FILENAME_LEN];
1371
};
1371
};
1372

    
   
1372

   
1373
/*! returns a new dahdi_chan_conf with default values (by-value) */
1373
/*! returns a new dahdi_chan_conf with default values (by-value) */
1374
static struct dahdi_chan_conf dahdi_chan_conf_default(void)
1374
static struct dahdi_chan_conf dahdi_chan_conf_default(void)
1375
{
1375
{
1376
	/* recall that if a field is not included here it is initialized
1376
	/* recall that if a field is not included here it is initialized
1377
	 * to 0 or equivalent
1377
	 * to 0 or equivalent
1378
	 */
1378
	 */
1379
	struct dahdi_chan_conf conf = {
1379
	struct dahdi_chan_conf conf = {
1380
#ifdef HAVE_PRI
1380
#ifdef HAVE_PRI
1381
		.pri.pri = {
1381
		.pri.pri = {
1382
			.nsf = PRI_NSF_NONE,
1382
			.nsf = PRI_NSF_NONE,
1383
			.switchtype = PRI_SWITCH_NI2,
1383
			.switchtype = PRI_SWITCH_NI2,
1384
			.dialplan = PRI_UNKNOWN + 1,
1384
			.dialplan = PRI_UNKNOWN + 1,
1385
			.localdialplan = PRI_NATIONAL_ISDN + 1,
1385
			.localdialplan = PRI_NATIONAL_ISDN + 1,
1386
			.nodetype = PRI_CPE,
1386
			.nodetype = PRI_CPE,
1387
			.qsigchannelmapping = DAHDI_CHAN_MAPPING_PHYSICAL,
1387
			.qsigchannelmapping = DAHDI_CHAN_MAPPING_PHYSICAL,
1388

    
   
1388

   
1389
#if defined(HAVE_PRI_CCSS)
1389
#if defined(HAVE_PRI_CCSS)
1390
			.cc_ptmp_recall_mode = 1,/* specificRecall */
1390
			.cc_ptmp_recall_mode = 1,/* specificRecall */
1391
			.cc_qsig_signaling_link_req = 1,/* retain */
1391
			.cc_qsig_signaling_link_req = 1,/* retain */
1392
			.cc_qsig_signaling_link_rsp = 1,/* retain */
1392
			.cc_qsig_signaling_link_rsp = 1,/* retain */
1393
#endif	/* defined(HAVE_PRI_CCSS) */
1393
#endif	/* defined(HAVE_PRI_CCSS) */
1394

    
   
1394

   
1395
			.minunused = 2,
1395
			.minunused = 2,
1396
			.idleext = "",
1396
			.idleext = "",
1397
			.idledial = "",
1397
			.idledial = "",
1398
			.internationalprefix = "",
1398
			.internationalprefix = "",
1399
			.nationalprefix = "",
1399
			.nationalprefix = "",
1400
			.localprefix = "",
1400
			.localprefix = "",
1401
			.privateprefix = "",
1401
			.privateprefix = "",
1402
			.unknownprefix = "",
1402
			.unknownprefix = "",
1403
			.resetinterval = -1,
1403
			.resetinterval = -1,
1404
		},
1404
		},
1405
#endif
1405
#endif
1406
#if defined(HAVE_SS7)
1406
#if defined(HAVE_SS7)
1407
		.ss7.ss7 = {
1407
		.ss7.ss7 = {
1408
			.called_nai = SS7_NAI_NATIONAL,
1408
			.called_nai = SS7_NAI_NATIONAL,
1409
			.calling_nai = SS7_NAI_NATIONAL,
1409
			.calling_nai = SS7_NAI_NATIONAL,
1410
			.internationalprefix = "",
1410
			.internationalprefix = "",
1411
			.nationalprefix = "",
1411
			.nationalprefix = "",
1412
			.subscriberprefix = "",
1412
			.subscriberprefix = "",
1413
			.unknownprefix = ""
1413
			.unknownprefix = ""
1414
		},
1414
		},
1415
#endif	/* defined(HAVE_SS7) */
1415
#endif	/* defined(HAVE_SS7) */
1416
#ifdef HAVE_OPENR2
1416
#ifdef HAVE_OPENR2
1417
		.mfcr2 = {
1417
		.mfcr2 = {
1418
			.variant = OR2_VAR_ITU,
1418
			.variant = OR2_VAR_ITU,
1419
			.mfback_timeout = -1,
1419
			.mfback_timeout = -1,
1420
			.metering_pulse_timeout = -1,
1420
			.metering_pulse_timeout = -1,
1421
			.max_ani = 10,
1421
			.max_ani = 10,
1422
			.max_dnis = 4,
1422
			.max_dnis = 4,
1423
			.get_ani_first = -1,
1423
			.get_ani_first = -1,
1424
#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
1424
#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
1425
			.skip_category_request = -1,
1425
			.skip_category_request = -1,
1426
#endif
1426
#endif
1427
			.call_files = 0,
1427
			.call_files = 0,
1428
			.allow_collect_calls = 0,
1428
			.allow_collect_calls = 0,
1429
			.charge_calls = 1,
1429
			.charge_calls = 1,
1430
			.accept_on_offer = 1,
1430
			.accept_on_offer = 1,
1431
			.forced_release = 0,
1431
			.forced_release = 0,
1432
			.double_answer = 0,
1432
			.double_answer = 0,
1433
			.immediate_accept = -1,
1433
			.immediate_accept = -1,
1434
#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
1434
#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 2
1435
			.dtmf_dialing = -1,
1435
			.dtmf_dialing = -1,
1436
			.dtmf_detection = -1,
1436
			.dtmf_detection = -1,
1437
			.dtmf_time_on = OR2_DEFAULT_DTMF_ON,
1437
			.dtmf_time_on = OR2_DEFAULT_DTMF_ON,
1438
			.dtmf_time_off = OR2_DEFAULT_DTMF_OFF,
1438
			.dtmf_time_off = OR2_DEFAULT_DTMF_OFF,
1439
#endif
1439
#endif
1440
#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 3
1440
#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 3
1441
			.dtmf_end_timeout = -1,
1441
			.dtmf_end_timeout = -1,
1442
#endif
1442
#endif
1443
			.logdir = "",
1443
			.logdir = "",
1444
			.r2proto_file = "",
1444
			.r2proto_file = "",
1445
			.loglevel = OR2_LOG_ERROR | OR2_LOG_WARNING,
1445
			.loglevel = OR2_LOG_ERROR | OR2_LOG_WARNING,
1446
			.category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER
1446
			.category = OR2_CALLING_PARTY_CATEGORY_NATIONAL_SUBSCRIBER
1447
		},
1447
		},
1448
#endif
1448
#endif
1449
		.chan = {
1449
		.chan = {
1450
			.context = "default",
1450
			.context = "default",
1451
			.cid_num = "",
1451
			.cid_num = "",
1452
			.cid_name = "",
1452
			.cid_name = "",
1453
			.cid_tag = "",
1453
			.cid_tag = "",
1454
			.mohinterpret = "default",
1454
			.mohinterpret = "default",
1455
			.mohsuggest = "",
1455
			.mohsuggest = "",
1456
			.parkinglot = "",
1456
			.parkinglot = "",
1457
			.transfertobusy = 1,
1457
			.transfertobusy = 1,
1458

    
   
1458

   
1459
			.cid_signalling = CID_SIG_BELL,
1459
			.cid_signalling = CID_SIG_BELL,
1460
			.cid_start = CID_START_RING,
1460
			.cid_start = CID_START_RING,
1461
			.dahditrcallerid = 0,
1461
			.dahditrcallerid = 0,
1462
			.use_callerid = 1,
1462
			.use_callerid = 1,
1463
			.sig = -1,
1463
			.sig = -1,
1464
			.outsigmod = -1,
1464
			.outsigmod = -1,
1465

    
   
1465

   
1466
			.cid_rxgain = +5.0,
1466
			.cid_rxgain = +5.0,
1467

    
   
1467

   
1468
			.tonezone = -1,
1468
			.tonezone = -1,
1469

    
   
1469

   
1470
			.echocancel.head.tap_length = 1,
1470
			.echocancel.head.tap_length = 1,
1471

    
   
1471

   
1472
			.busycount = 3,
1472
			.busycount = 3,
1473

    
   
1473

   
1474
			.accountcode = "",
1474
			.accountcode = "",
1475

    
   
1475

   
1476
			.mailbox = "",
1476
			.mailbox = "",
1477

    
   
1477

   
1478
#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
1478
#ifdef HAVE_DAHDI_LINEREVERSE_VMWI
1479
			.mwisend_fsk = 1,
1479
			.mwisend_fsk = 1,
1480
#endif
1480
#endif
1481
			.polarityonanswerdelay = 600,
1481
			.polarityonanswerdelay = 600,
1482

    
   
1482

   
1483
			.sendcalleridafter = DEFAULT_CIDRINGS,
1483
			.sendcalleridafter = DEFAULT_CIDRINGS,
1484

    
   
1484

   
1485
			.buf_policy = DAHDI_POLICY_IMMEDIATE,
1485
			.buf_policy = DAHDI_POLICY_IMMEDIATE,
1486
			.buf_no = numbufs,
1486
			.buf_no = numbufs,
1487
			.usefaxbuffers = 0,
1487
			.usefaxbuffers = 0,
1488
			.cc_params = ast_cc_config_params_init(),
1488
			.cc_params = ast_cc_config_params_init(),
1489
		},
1489
		},
1490
		.timing = {
1490
		.timing = {
1491
			.prewinktime = -1,
1491
			.prewinktime = -1,
1492
			.preflashtime = -1,
1492
			.preflashtime = -1,
1493
			.winktime = -1,
1493
			.winktime = -1,
1494
			.flashtime = -1,
1494
			.flashtime = -1,
1495
			.starttime = -1,
1495
			.starttime = -1,
1496
			.rxwinktime = -1,
1496
			.rxwinktime = -1,
1497
			.rxflashtime = -1,
1497
			.rxflashtime = -1,
1498
			.debouncetime = -1
1498
			.debouncetime = -1
1499
		},
1499
		},
1500
		.is_sig_auto = 1,
1500
		.is_sig_auto = 1,
1501
		.smdi_port = "/dev/ttyS0",
1501
		.smdi_port = "/dev/ttyS0",
1502
	};
1502
	};
1503

    
   
1503

   
1504
	return conf;
1504
	return conf;
1505
}
1505
}
1506

    
   
1506

   
1507

    
   
1507

   
1508
static struct ast_channel *dahdi_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause);
1508
static struct ast_channel *dahdi_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause);
1509
static int dahdi_digit_begin(struct ast_channel *ast, char digit);
1509
static int dahdi_digit_begin(struct ast_channel *ast, char digit);
1510
static int dahdi_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
1510
static int dahdi_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
1511
static int dahdi_sendtext(struct ast_channel *c, const char *text);
1511
static int dahdi_sendtext(struct ast_channel *c, const char *text);
1512
static int dahdi_call(struct ast_channel *ast, char *rdest, int timeout);
1512
static int dahdi_call(struct ast_channel *ast, char *rdest, int timeout);
1513
static int dahdi_hangup(struct ast_channel *ast);
1513
static int dahdi_hangup(struct ast_channel *ast);
1514
static int dahdi_answer(struct ast_channel *ast);
1514
static int dahdi_answer(struct ast_channel *ast);
1515
static struct ast_frame *dahdi_read(struct ast_channel *ast);
1515
static struct ast_frame *dahdi_read(struct ast_channel *ast);
1516
static int dahdi_write(struct ast_channel *ast, struct ast_frame *frame);
1516
static int dahdi_write(struct ast_channel *ast, struct ast_frame *frame);
1517
static struct ast_frame *dahdi_exception(struct ast_channel *ast);
1517
static struct ast_frame *dahdi_exception(struct ast_channel *ast);
1518
static int dahdi_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen);
1518
static int dahdi_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen);
1519
static int dahdi_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
1519
static int dahdi_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
1520
static int dahdi_setoption(struct ast_channel *chan, int option, void *data, int datalen);
1520
static int dahdi_setoption(struct ast_channel *chan, int option, void *data, int datalen);
1521
static int dahdi_queryoption(struct ast_channel *chan, int option, void *data, int *datalen);
1521
static int dahdi_queryoption(struct ast_channel *chan, int option, void *data, int *datalen);
1522
static int dahdi_func_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t len);
1522
static int dahdi_func_read(struct ast_channel *chan, const char *function, char *data, char *buf, size_t len);
1523
static int dahdi_func_write(struct ast_channel *chan, const char *function, char *data, const char *value);
1523
static int dahdi_func_write(struct ast_channel *chan, const char *function, char *data, const char *value);
1524
static int dahdi_devicestate(void *data);
1524
static int dahdi_devicestate(void *data);
1525
static int dahdi_cc_callback(struct ast_channel *inbound, const char *dest, ast_cc_callback_fn callback);
1525
static int dahdi_cc_callback(struct ast_channel *inbound, const char *dest, ast_cc_callback_fn callback);
1526

    
   
1526

   
1527
static struct ast_channel_tech dahdi_tech = {
1527
static struct ast_channel_tech dahdi_tech = {
1528
	.type = "DAHDI",
1528
	.type = "DAHDI",
1529
	.description = tdesc,
1529
	.description = tdesc,
1530
	.requester = dahdi_request,
1530
	.requester = dahdi_request,
1531
	.send_digit_begin = dahdi_digit_begin,
1531
	.send_digit_begin = dahdi_digit_begin,
1532
	.send_digit_end = dahdi_digit_end,
1532
	.send_digit_end = dahdi_digit_end,
1533
	.send_text = dahdi_sendtext,
1533
	.send_text = dahdi_sendtext,
1534
	.call = dahdi_call,
1534
	.call = dahdi_call,
1535
	.hangup = dahdi_hangup,
1535
	.hangup = dahdi_hangup,
1536
	.answer = dahdi_answer,
1536
	.answer = dahdi_answer,
1537
	.read = dahdi_read,
1537
	.read = dahdi_read,
1538
	.write = dahdi_write,
1538
	.write = dahdi_write,
1539
	.bridge = dahdi_bridge,
1539
	.bridge = dahdi_bridge,
1540
	.exception = dahdi_exception,
1540
	.exception = dahdi_exception,
1541
	.indicate = dahdi_indicate,
1541
	.indicate = dahdi_indicate,
1542
	.fixup = dahdi_fixup,
1542
	.fixup = dahdi_fixup,
1543
	.setoption = dahdi_setoption,
1543
	.setoption = dahdi_setoption,
1544
	.queryoption = dahdi_queryoption,
1544
	.queryoption = dahdi_queryoption,
1545
	.func_channel_read = dahdi_func_read,
1545
	.func_channel_read = dahdi_func_read,
1546
	.func_channel_write = dahdi_func_write,
1546
	.func_channel_write = dahdi_func_write,
1547
	.devicestate = dahdi_devicestate,
1547
	.devicestate = dahdi_devicestate,
1548
	.cc_callback = dahdi_cc_callback,
1548
	.cc_callback = dahdi_cc_callback,
1549
};
1549
};
1550

    
   
1550

   
1551
#define GET_CHANNEL(p) ((p)->channel)
1551
#define GET_CHANNEL(p) ((p)->channel)
1552

    
   
1552

   
1553
#define SIG_PRI_LIB_HANDLE_CASES	\
1553
#define SIG_PRI_LIB_HANDLE_CASES	\
1554
	SIG_PRI:						\
1554
	SIG_PRI:						\
1555
	case SIG_BRI:					\
1555
	case SIG_BRI:					\
1556
	case SIG_BRI_PTMP
1556
	case SIG_BRI_PTMP
1557

    
   
1557

   
1558
/*!
1558
/*!
1559
 * \internal
1559
 * \internal
1560
 * \brief Determine if sig_pri handles the signaling.
1560
 * \brief Determine if sig_pri handles the signaling.
1561
 * \since 1.8
1561
 * \since 1.8
1562
 *
1562
 *
1563
 * \param signaling Signaling to determine if is for sig_pri.
1563
 * \param signaling Signaling to determine if is for sig_pri.
1564
 *
1564
 *
1565
 * \return TRUE if the signaling is for sig_pri.
1565
 * \return TRUE if the signaling is for sig_pri.
1566
 */
1566
 */
1567
static inline int dahdi_sig_pri_lib_handles(int signaling)
1567
static inline int dahdi_sig_pri_lib_handles(int signaling)
1568
{
1568
{
1569
	int handles;
1569
	int handles;
1570

    
   
1570

   
1571
	switch (signaling) {
1571
	switch (signaling) {
1572
	case SIG_PRI_LIB_HANDLE_CASES:
1572
	case SIG_PRI_LIB_HANDLE_CASES:
1573
		handles = 1;
1573
		handles = 1;
1574
		break;
1574
		break;
1575
	default:
1575
	default:
1576
		handles = 0;
1576
		handles = 0;
1577
		break;
1577
		break;
1578
	}
1578
	}
1579

    
   
1579

   
1580
	return handles;
1580
	return handles;
1581
}
1581
}
1582

    
   
1582

   
1583
static enum analog_sigtype dahdisig_to_analogsig(int sig)
1583
static enum analog_sigtype dahdisig_to_analogsig(int sig)
1584
{
1584
{
1585
	switch (sig) {
1585
	switch (sig) {
1586
	case SIG_FXOLS:
1586
	case SIG_FXOLS:
1587
		return ANALOG_SIG_FXOLS;
1587
		return ANALOG_SIG_FXOLS;
1588
	case SIG_FXOGS:
1588
	case SIG_FXOGS:
1589
		return ANALOG_SIG_FXOGS;
1589
		return ANALOG_SIG_FXOGS;
1590
	case SIG_FXOKS:
1590
	case SIG_FXOKS:
1591
		return ANALOG_SIG_FXOKS;
1591
		return ANALOG_SIG_FXOKS;
1592
	case SIG_FXSLS:
1592
	case SIG_FXSLS:
1593
		return ANALOG_SIG_FXSLS;
1593
		return ANALOG_SIG_FXSLS;
1594
	case SIG_FXSGS:
1594
	case SIG_FXSGS:
1595
		return ANALOG_SIG_FXSGS;
1595
		return ANALOG_SIG_FXSGS;
1596
	case SIG_FXSKS:
1596
	case SIG_FXSKS:
1597
		return ANALOG_SIG_FXSKS;
1597
		return ANALOG_SIG_FXSKS;
1598
	case SIG_EMWINK:
1598
	case SIG_EMWINK:
1599
		return ANALOG_SIG_EMWINK;
1599
		return ANALOG_SIG_EMWINK;
1600
	case SIG_EM:
1600
	case SIG_EM:
1601
		return ANALOG_SIG_EM;
1601
		return ANALOG_SIG_EM;
1602
	case SIG_EM_E1:
1602
	case SIG_EM_E1:
1603
		return ANALOG_SIG_EM_E1;
1603
		return ANALOG_SIG_EM_E1;
1604
	case SIG_FEATD:
1604
	case SIG_FEATD:
1605
		return ANALOG_SIG_FEATD;
1605
		return ANALOG_SIG_FEATD;
1606
	case SIG_FEATDMF:
1606
	case SIG_FEATDMF:
1607
		return ANALOG_SIG_FEATDMF;
1607
		return ANALOG_SIG_FEATDMF;
1608
	case SIG_E911:
1608
	case SIG_E911:
1609
		return SIG_E911;
1609
		return SIG_E911;
1610
	case SIG_FGC_CAMA:
1610
	case SIG_FGC_CAMA:
1611
		return ANALOG_SIG_FGC_CAMA;
1611
		return ANALOG_SIG_FGC_CAMA;
1612
	case SIG_FGC_CAMAMF:
1612
	case SIG_FGC_CAMAMF:
1613
		return ANALOG_SIG_FGC_CAMAMF;
1613
		return ANALOG_SIG_FGC_CAMAMF;
1614
	case SIG_FEATB:
1614
	case SIG_FEATB:
1615
		return ANALOG_SIG_FEATB;
1615
		return ANALOG_SIG_FEATB;
1616
	case SIG_SFWINK:
1616
	case SIG_SFWINK:
1617
		return ANALOG_SIG_SFWINK;
1617
		return ANALOG_SIG_SFWINK;
1618
	case SIG_SF:
1618
	case SIG_SF:
1619
		return ANALOG_SIG_SF;
1619
		return ANALOG_SIG_SF;
1620
	case SIG_SF_FEATD:
1620
	case SIG_SF_FEATD:
1621
		return ANALOG_SIG_SF_FEATD;
1621
		return ANALOG_SIG_SF_FEATD;
1622
	case SIG_SF_FEATDMF:
1622
	case SIG_SF_FEATDMF:
1623
		return ANALOG_SIG_SF_FEATDMF;
1623
		return ANALOG_SIG_SF_FEATDMF;
1624
	case SIG_FEATDMF_TA:
1624
	case SIG_FEATDMF_TA:
1625
		return ANALOG_SIG_FEATDMF_TA;
1625
		return ANALOG_SIG_FEATDMF_TA;
1626
	case SIG_SF_FEATB:
1626
	case SIG_SF_FEATB:
1627
		return ANALOG_SIG_FEATB;
1627
		return ANALOG_SIG_FEATB;
1628
	default:
1628
	default:
1629
		return -1;
1629
		return -1;
1630
	}
1630
	}
1631
}
1631
}
1632

    
   
1632

   
1633

    
   
1633

   
1634
static int analog_tone_to_dahditone(enum analog_tone tone)
1634
static int analog_tone_to_dahditone(enum analog_tone tone)
1635
{
1635
{
1636
	switch (tone) {
1636
	switch (tone) {
1637
	case ANALOG_TONE_RINGTONE:
1637
	case ANALOG_TONE_RINGTONE:
1638
		return DAHDI_TONE_RINGTONE;
1638
		return DAHDI_TONE_RINGTONE;
1639
	case ANALOG_TONE_STUTTER:
1639
	case ANALOG_TONE_STUTTER:
1640
		return DAHDI_TONE_STUTTER;
1640
		return DAHDI_TONE_STUTTER;
1641
	case ANALOG_TONE_CONGESTION:
1641
	case ANALOG_TONE_CONGESTION:
1642
		return DAHDI_TONE_CONGESTION;
1642
		return DAHDI_TONE_CONGESTION;
1643
	case ANALOG_TONE_DIALTONE:
1643
	case ANALOG_TONE_DIALTONE:
1644
		return DAHDI_TONE_DIALTONE;
1644
		return DAHDI_TONE_DIALTONE;
1645
	case ANALOG_TONE_DIALRECALL:
1645
	case ANALOG_TONE_DIALRECALL:
1646
		return DAHDI_TONE_DIALRECALL;
1646
		return DAHDI_TONE_DIALRECALL;
1647
	case ANALOG_TONE_INFO:
1647
	case ANALOG_TONE_INFO:
1648
		return DAHDI_TONE_INFO;
1648
		return DAHDI_TONE_INFO;
1649
	default:
1649
	default:
1650
		return -1;
1650
		return -1;
1651
	}
1651
	}
1652
}
1652
}
1653

    
   
1653

   
1654
static int analogsub_to_dahdisub(enum analog_sub analogsub)
1654
static int analogsub_to_dahdisub(enum analog_sub analogsub)
1655
{
1655
{
1656
	int index;
1656
	int index;
1657

    
   
1657

   
1658
	switch (analogsub) {
1658
	switch (analogsub) {
1659
	case ANALOG_SUB_REAL:
1659
	case ANALOG_SUB_REAL:
1660
		index = SUB_REAL;
1660
		index = SUB_REAL;
1661
		break;
1661
		break;
1662
	case ANALOG_SUB_CALLWAIT:
1662
	case ANALOG_SUB_CALLWAIT:
1663
		index = SUB_CALLWAIT;
1663
		index = SUB_CALLWAIT;
1664
		break;
1664
		break;
1665
	case ANALOG_SUB_THREEWAY:
1665
	case ANALOG_SUB_THREEWAY:
1666
		index = SUB_THREEWAY;
1666
		index = SUB_THREEWAY;
1667
		break;
1667
		break;
1668
	default:
1668
	default:
1669
		ast_log(LOG_ERROR, "Unidentified sub!\n");
1669
		ast_log(LOG_ERROR, "Unidentified sub!\n");
1670
		index = SUB_REAL;
1670
		index = SUB_REAL;
1671
	}
1671
	}
1672

    
   
1672

   
1673
	return index;
1673
	return index;
1674
}
1674
}
1675

    
   
1675

   
1676
static enum analog_event dahdievent_to_analogevent(int event);
1676
static enum analog_event dahdievent_to_analogevent(int event);
1677
static int bump_gains(struct dahdi_pvt *p);
1677
static int bump_gains(struct dahdi_pvt *p);
1678
static int dahdi_setlinear(int dfd, int linear);
1678
static int dahdi_setlinear(int dfd, int linear);
1679

    
   
1679

   
1680
static int my_start_cid_detect(void *pvt, int cid_signalling)
1680
static int my_start_cid_detect(void *pvt, int cid_signalling)
1681
{
1681
{
1682
	struct dahdi_pvt *p = pvt;
1682
	struct dahdi_pvt *p = pvt;
1683
	int index = SUB_REAL;
1683
	int index = SUB_REAL;
1684
	p->cs = callerid_new(cid_signalling);
1684
	p->cs = callerid_new(cid_signalling);
1685
	if (!p->cs) {
1685
	if (!p->cs) {
1686
		ast_log(LOG_ERROR, "Unable to alloc callerid\n");
1686
		ast_log(LOG_ERROR, "Unable to alloc callerid\n");
1687
		return -1;
1687
		return -1;
1688
	}
1688
	}
1689
	bump_gains(p);
1689
	bump_gains(p);
1690
	dahdi_setlinear(p->subs[index].dfd, 0);
1690
	dahdi_setlinear(p->subs[index].dfd, 0);
1691

    
   
1691

   
1692
	return 0;
1692
	return 0;
1693
}
1693
}
1694

    
   
1694

   
1695
static int my_stop_cid_detect(void *pvt)
1695
static int my_stop_cid_detect(void *pvt)
1696
{
1696
{
1697
	struct dahdi_pvt *p = pvt;
1697
	struct dahdi_pvt *p = pvt;
1698
	int index = SUB_REAL;
1698
	int index = SUB_REAL;
1699
	if (p->cs)
1699
	if (p->cs)
1700
		callerid_free(p->cs);
1700
		callerid_free(p->cs);
1701
	dahdi_setlinear(p->subs[index].dfd, p->subs[index].linear);
1701
	dahdi_setlinear(p->subs[index].dfd, p->subs[index].linear);
1702
	return 0;
1702
	return 0;
1703
}
1703
}
1704

    
   
1704

   
1705
static int my_get_callerid(void *pvt, char *namebuf, char *numbuf, enum analog_event *ev, size_t timeout)
1705
static int my_get_callerid(void *pvt, char *namebuf, char *numbuf, enum analog_event *ev, size_t timeout)
1706
{
1706
{
1707
	struct dahdi_pvt *p = pvt;
1707
	struct dahdi_pvt *p = pvt;
1708
	struct analog_pvt *analog_p = p->sig_pvt;
1708
	struct analog_pvt *analog_p = p->sig_pvt;
1709
	struct pollfd poller;
1709
	struct pollfd poller;
1710
	char *name, *num;
1710
	char *name, *num;
1711
	int index = SUB_REAL;
1711
	int index = SUB_REAL;
1712
	int res;
1712
	int res;
1713
	unsigned char buf[256];
1713
	unsigned char buf[256];
1714
	int flags;
1714
	int flags;
1715
	struct ast_format tmpfmt;
1715
	struct ast_format tmpfmt;
1716

    
   
1716

   
1717
	poller.fd = p->subs[SUB_REAL].dfd;
1717
	poller.fd = p->subs[SUB_REAL].dfd;
1718
	poller.events = POLLPRI | POLLIN;
1718
	poller.events = POLLPRI | POLLIN;
1719
	poller.revents = 0;
1719
	poller.revents = 0;
1720

    
   
1720

   
1721
	res = poll(&poller, 1, timeout);
1721
	res = poll(&poller, 1, timeout);
1722

    
   
1722

   
1723
	if (poller.revents & POLLPRI) {
1723
	if (poller.revents & POLLPRI) {
1724
		*ev = dahdievent_to_analogevent(dahdi_get_event(p->subs[SUB_REAL].dfd));
1724
		*ev = dahdievent_to_analogevent(dahdi_get_event(p->subs[SUB_REAL].dfd));
1725
		return 1;
1725
		return 1;
1726
	}
1726
	}
1727

    
   
1727

   
1728
	if (poller.revents & POLLIN) {
1728
	if (poller.revents & POLLIN) {
1729
		/*** NOTES ***/
1729
		/*** NOTES ***/
1730
		/* Change API: remove cid_signalling from get_callerid, add a new start_cid_detect and stop_cid_detect function
1730
		/* Change API: remove cid_signalling from get_callerid, add a new start_cid_detect and stop_cid_detect function
1731
		 * to enable slin mode and allocate cid detector. get_callerid should be able to be called any number of times until
1731
		 * to enable slin mode and allocate cid detector. get_callerid should be able to be called any number of times until
1732
		 * either a timeout occurs or CID is detected (returns 0). returning 1 should be event received, and -1 should be
1732
		 * either a timeout occurs or CID is detected (returns 0). returning 1 should be event received, and -1 should be
1733
		 * a failure and die, and returning 2 means no event was received. */
1733
		 * a failure and die, and returning 2 means no event was received. */
1734
		res = read(p->subs[index].dfd, buf, sizeof(buf));
1734
		res = read(p->subs[index].dfd, buf, sizeof(buf));
1735
		if (res < 0) {
1735
		if (res < 0) {
1736
			if (errno != ELAST) {
1736
			if (errno != ELAST) {
1737
				ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
1737
				ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
1738
				callerid_free(p->cs);
1738
				callerid_free(p->cs);
1739
				return -1;
1739
				return -1;
1740
			}
1740
			}
1741
		}
1741
		}
1742

    
   
1742

   
1743
		if (analog_p->ringt > 0) {
1743
		if (analog_p->ringt > 0) {
1744
			if (!(--analog_p->ringt)) {
1744
			if (!(--analog_p->ringt)) {
1745
				/* only return if we timeout from a ring event */
1745
				/* only return if we timeout from a ring event */
1746
				return -1;
1746
				return -1;
1747
			}
1747
			}
1748
		}
1748
		}
1749

    
   
1749

   
1750
		if (p->cid_signalling == CID_SIG_V23_JP) {
1750
		if (p->cid_signalling == CID_SIG_V23_JP) {
1751
			res = callerid_feed_jp(p->cs, buf, res, ast_format_set(&tmpfmt, AST_LAW(p), 0));
1751
			res = callerid_feed_jp(p->cs, buf, res, ast_format_set(&tmpfmt, AST_LAW(p), 0));
1752
		} else {
1752
		} else {
1753
			res = callerid_feed(p->cs, buf, res, ast_format_set(&tmpfmt, AST_LAW(p), 0));
1753
			res = callerid_feed(p->cs, buf, res, ast_format_set(&tmpfmt, AST_LAW(p), 0));
1754
		}
1754
		}
1755
		if (res < 0) {
1755
		if (res < 0) {
1756
			/*
1756
			/*
1757
			 * The previous diagnostic message output likely
1757
			 * The previous diagnostic message output likely
1758
			 * explains why it failed.
1758
			 * explains why it failed.
1759
			 */
1759
			 */
1760
			ast_log(LOG_WARNING, "Failed to decode CallerID\n");
1760
			ast_log(LOG_WARNING, "Failed to decode CallerID\n");
1761
			return -1;
1761
			return -1;
1762
		}
1762
		}
1763

    
   
1763

   
1764
		if (res == 1) {
1764
		if (res == 1) {
1765
			callerid_get(p->cs, &name, &num, &flags);
1765
			callerid_get(p->cs, &name, &num, &flags);
1766
			if (name)
1766
			if (name)
1767
				ast_copy_string(namebuf, name, ANALOG_MAX_CID);
1767
				ast_copy_string(namebuf, name, ANALOG_MAX_CID);
1768
			if (num)
1768
			if (num)
1769
				ast_copy_string(numbuf, num, ANALOG_MAX_CID);
1769
				ast_copy_string(numbuf, num, ANALOG_MAX_CID);
1770

    
   
1770

   
1771
			ast_debug(1, "CallerID number: %s, name: %s, flags=%d\n", num, name, flags);
1771
			ast_debug(1, "CallerID number: %s, name: %s, flags=%d\n", num, name, flags);
1772
			return 0;
1772
			return 0;
1773
		}
1773
		}
1774
	}
1774
	}
1775

    
   
1775

   
1776
	*ev = ANALOG_EVENT_NONE;
1776
	*ev = ANALOG_EVENT_NONE;
1777
	return 2;
1777
	return 2;
1778
}
1778
}
1779

    
   
1779

   
1780
static const char *event2str(int event);
1780
static const char *event2str(int event);
1781
static int restore_gains(struct dahdi_pvt *p);
1781
static int restore_gains(struct dahdi_pvt *p);
1782

    
   
1782

   
1783
static int my_distinctive_ring(struct ast_channel *chan, void *pvt, int idx, int *ringdata)
1783
static int my_distinctive_ring(struct ast_channel *chan, void *pvt, int idx, int *ringdata)
1784
{
1784
{
1785
	unsigned char buf[256];
1785
	unsigned char buf[256];
1786
	int distMatches;
1786
	int distMatches;
1787
	int curRingData[RING_PATTERNS];
1787
	int curRingData[RING_PATTERNS];
1788
	int receivedRingT;
1788
	int receivedRingT;
1789
	int counter1;
1789
	int counter1;
1790
	int counter;
1790
	int counter;
1791
	int i;
1791
	int i;
1792
	int res;
1792
	int res;
1793
	int checkaftercid = 0;
1793
	int checkaftercid = 0;
1794

    
   
1794

   
1795
	struct dahdi_pvt *p = pvt;
1795
	struct dahdi_pvt *p = pvt;
1796
	struct analog_pvt *analog_p = p->sig_pvt;
1796
	struct analog_pvt *analog_p = p->sig_pvt;
1797

    
   
1797

   
1798
	if (ringdata == NULL) {
1798
	if (ringdata == NULL) {
1799
		ringdata = curRingData;
1799
		ringdata = curRingData;
1800
	} else {
1800
	} else {
1801
		checkaftercid = 1;
1801
		checkaftercid = 1;
1802
	}
1802
	}
1803

    
   
1803

   
1804
	/* We must have a ring by now, so, if configured, lets try to listen for
1804
	/* We must have a ring by now, so, if configured, lets try to listen for
1805
	 * distinctive ringing */
1805
	 * distinctive ringing */
1806
	if ((checkaftercid && distinctiveringaftercid) || !checkaftercid) {
1806
	if ((checkaftercid && distinctiveringaftercid) || !checkaftercid) {
1807
		/* Clear the current ring data array so we don't have old data in it. */
1807
		/* Clear the current ring data array so we don't have old data in it. */
1808
		for (receivedRingT = 0; receivedRingT < RING_PATTERNS; receivedRingT++)
1808
		for (receivedRingT = 0; receivedRingT < RING_PATTERNS; receivedRingT++)
1809
			ringdata[receivedRingT] = 0;
1809
			ringdata[receivedRingT] = 0;
1810
		receivedRingT = 0;
1810
		receivedRingT = 0;
1811
		if (checkaftercid && distinctiveringaftercid)
1811
		if (checkaftercid && distinctiveringaftercid)
1812
			ast_verb(3, "Detecting post-CID distinctive ring\n");
1812
			ast_verb(3, "Detecting post-CID distinctive ring\n");
1813
		/* Check to see if context is what it should be, if not set to be. */
1813
		/* Check to see if context is what it should be, if not set to be. */
1814
		else if (strcmp(p->context,p->defcontext) != 0) {
1814
		else if (strcmp(p->context,p->defcontext) != 0) {
1815
			ast_copy_string(p->context, p->defcontext, sizeof(p->context));
1815
			ast_copy_string(p->context, p->defcontext, sizeof(p->context));
1816
			ast_copy_string(chan->context,p->defcontext,sizeof(chan->context));
1816
			ast_copy_string(chan->context,p->defcontext,sizeof(chan->context));
1817
		}
1817
		}
1818

    
   
1818

   
1819
		for (;;) {
1819
		for (;;) {
1820
			i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
1820
			i = DAHDI_IOMUX_READ | DAHDI_IOMUX_SIGEVENT;
1821
			if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) {
1821
			if ((res = ioctl(p->subs[idx].dfd, DAHDI_IOMUX, &i))) {
1822
				ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
1822
				ast_log(LOG_WARNING, "I/O MUX failed: %s\n", strerror(errno));
1823
				ast_hangup(chan);
1823
				ast_hangup(chan);
1824
				return 1;
1824
				return 1;
1825
			}
1825
			}
1826
			if (i & DAHDI_IOMUX_SIGEVENT) {
1826
			if (i & DAHDI_IOMUX_SIGEVENT) {
1827
				res = dahdi_get_event(p->subs[idx].dfd);
1827
				res = dahdi_get_event(p->subs[idx].dfd);
1828
				if (res == DAHDI_EVENT_NOALARM) {
1828
				if (res == DAHDI_EVENT_NOALARM) {
1829
					p->inalarm = 0;
1829
					p->inalarm = 0;
1830
					analog_p->inalarm = 0;
1830
					analog_p->inalarm = 0;
1831
				}
1831
				}
1832
				ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
1832
				ast_log(LOG_NOTICE, "Got event %d (%s)...\n", res, event2str(res));
1833
				res = 0;
1833
				res = 0;
1834
				/* Let us detect distinctive ring */
1834
				/* Let us detect distinctive ring */
1835

    
   
1835

   
1836
				ringdata[receivedRingT] = analog_p->ringt;
1836
				ringdata[receivedRingT] = analog_p->ringt;
1837

    
   
1837

   
1838
				if (analog_p->ringt < analog_p->ringt_base/2)
1838
				if (analog_p->ringt < analog_p->ringt_base/2)
1839
					break;
1839
					break;
1840
				/* Increment the ringT counter so we can match it against
1840
				/* Increment the ringT counter so we can match it against
1841
				   values in chan_dahdi.conf for distinctive ring */
1841
				   values in chan_dahdi.conf for distinctive ring */
1842
				if (++receivedRingT == RING_PATTERNS)
1842
				if (++receivedRingT == RING_PATTERNS)
1843
					break;
1843
					break;
1844
			} else if (i & DAHDI_IOMUX_READ) {
1844
			} else if (i & DAHDI_IOMUX_READ) {
1845
				res = read(p->subs[idx].dfd, buf, sizeof(buf));
1845
				res = read(p->subs[idx].dfd, buf, sizeof(buf));
1846
				if (res < 0) {
1846
				if (res < 0) {
1847
					if (errno != ELAST) {
1847
					if (errno != ELAST) {
1848
						ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
1848
						ast_log(LOG_WARNING, "read returned error: %s\n", strerror(errno));
1849
						ast_hangup(chan);
1849
						ast_hangup(chan);
1850
						return 1;
1850
						return 1;
1851
					}
1851
					}
1852
					break;
1852
					break;
1853
				}
1853
				}
1854
				if (analog_p->ringt > 0) {
1854
				if (analog_p->ringt > 0) {
1855
					if (!(--analog_p->ringt)) {
1855
					if (!(--analog_p->ringt)) {
1856
						res = -1;
1856
						res = -1;
1857
						break;
1857
						break;
1858
					}
1858
					}
1859
				}
1859
				}
1860
			}
1860
			}
1861
		}
1861
		}
1862
	}
1862
	}
1863
	if ((checkaftercid && usedistinctiveringdetection) || !checkaftercid) {
1863
	if ((checkaftercid && usedistinctiveringdetection) || !checkaftercid) {
1864
		/* this only shows up if you have n of the dring patterns filled in */
1864
		/* this only shows up if you have n of the dring patterns filled in */
1865
		ast_verb(3, "Detected ring pattern: %d,%d,%d\n",ringdata[0],ringdata[1],ringdata[2]);
1865
		ast_verb(3, "Detected ring pattern: %d,%d,%d\n",ringdata[0],ringdata[1],ringdata[2]);
1866
		for (counter = 0; counter < 3; counter++) {
1866
		for (counter = 0; counter < 3; counter++) {
1867
		/* Check to see if the rings we received match any of the ones in chan_dahdi.conf for this channel */
1867
		/* Check to see if the rings we received match any of the ones in chan_dahdi.conf for this channel */
1868
			distMatches = 0;
1868
			distMatches = 0;
1869
			/* this only shows up if you have n of the dring patterns filled in */
1869
			/* this only shows up if you have n of the dring patterns filled in */
1870
			ast_verb(3, "Checking %d,%d,%d\n",
1870
			ast_verb(3, "Checking %d,%d,%d\n",
1871
					p->drings.ringnum[counter].ring[0],
1871
					p->drings.ringnum[counter].ring[0],
1872
					p->drings.ringnum[counter].ring[1],
1872
					p->drings.ringnum[counter].ring[1],
1873
					p->drings.ringnum[counter].ring[2]);
1873
					p->drings.ringnum[counter].ring[2]);
1874
			for (counter1 = 0; counter1 < 3; counter1++) {
1874
			for (counter1 = 0; counter1 < 3; counter1++) {
1875
				ast_verb(3, "Ring pattern check range: %d\n", p->drings.ringnum[counter].range);
1875
				ast_verb(3, "Ring pattern check range: %d\n", p->drings.ringnum[counter].range);
1876
				if (p->drings.ringnum[counter].ring[counter1] == -1) {
1876
				if (p->drings.ringnum[counter].ring[counter1] == -1) {
1877
					ast_verb(3, "Pattern ignore (-1) detected, so matching pattern %d regardless.\n",
1877
					ast_verb(3, "Pattern ignore (-1) detected, so matching pattern %d regardless.\n",
1878
					ringdata[counter1]);
1878
					ringdata[counter1]);
1879
					distMatches++;
1879
					distMatches++;
1880
				} else if (ringdata[counter1] <= (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range) &&
1880
				} else if (ringdata[counter1] <= (p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range) &&
1881
										ringdata[counter1] >= (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range)) {
1881
										ringdata[counter1] >= (p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range)) {
1882
					ast_verb(3, "Ring pattern matched in range: %d to %d\n",
1882
					ast_verb(3, "Ring pattern matched in range: %d to %d\n",
1883
					(p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range),
1883
					(p->drings.ringnum[counter].ring[counter1] - p->drings.ringnum[counter].range),
1884
					(p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range));
1884
					(p->drings.ringnum[counter].ring[counter1] + p->drings.ringnum[counter].range));
1885
					distMatches++;
1885
					distMatches++;
1886
				}
1886
				}
1887
			}
1887
			}
1888

    
   
1888

   
1889
			if (distMatches == 3) {
1889
			if (distMatches == 3) {
1890
				/* The ring matches, set the context to whatever is for distinctive ring.. */
1890
				/* The ring matches, set the context to whatever is for distinctive ring.. */
1891
				ast_copy_string(p->context, S_OR(p->drings.ringContext[counter].contextData, p->defcontext), sizeof(p->context));
1891
				ast_copy_string(p->context, S_OR(p->drings.ringContext[counter].contextData, p->defcontext), sizeof(p->context));
1892
				ast_copy_string(chan->context, S_OR(p->drings.ringContext[counter].contextData, p->defcontext), sizeof(chan->context));
1892
				ast_copy_string(chan->context, S_OR(p->drings.ringContext[counter].contextData, p->defcontext), sizeof(chan->context));
1893
				ast_verb(3, "Distinctive Ring matched context %s\n",p->context);
1893
				ast_verb(3, "Distinctive Ring matched context %s\n",p->context);
1894
				break;
1894
				break;
1895
			}
1895
			}
1896
		}
1896
		}
1897
	}
1897
	}
1898
	/* Restore linear mode (if appropriate) for Caller*ID processing */
1898
	/* Restore linear mode (if appropriate) for Caller*ID processing */
1899
	dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
1899
	dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
1900
	restore_gains(p);
1900
	restore_gains(p);
1901

    
   
1901

   
1902
	return 0;
1902
	return 0;
1903
}
1903
}
1904

    
   
1904

   
1905
static int my_stop_callwait(void *pvt)
1905
static int my_stop_callwait(void *pvt)
1906
{
1906
{
1907
	struct dahdi_pvt *p = pvt;
1907
	struct dahdi_pvt *p = pvt;
1908
	p->callwaitingrepeat = 0;
1908
	p->callwaitingrepeat = 0;
1909
	p->cidcwexpire = 0;
1909
	p->cidcwexpire = 0;
1910
	p->cid_suppress_expire = 0;
1910
	p->cid_suppress_expire = 0;
1911

    
   
1911

   
1912
	return 0;
1912
	return 0;
1913
}
1913
}
1914

    
   
1914

   
1915
static int send_callerid(struct dahdi_pvt *p);
1915
static int send_callerid(struct dahdi_pvt *p);
1916
static int save_conference(struct dahdi_pvt *p);
1916
static int save_conference(struct dahdi_pvt *p);
1917
static int restore_conference(struct dahdi_pvt *p);
1917
static int restore_conference(struct dahdi_pvt *p);
1918

    
   
1918

   
1919
static int my_callwait(void *pvt)
1919
static int my_callwait(void *pvt)
1920
{
1920
{
1921
	struct dahdi_pvt *p = pvt;
1921
	struct dahdi_pvt *p = pvt;
1922
	struct ast_format tmpfmt;
1922
	struct ast_format tmpfmt;
1923
	p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES;
1923
	p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES;
1924
	if (p->cidspill) {
1924
	if (p->cidspill) {
1925
		ast_log(LOG_WARNING, "Spill already exists?!?\n");
1925
		ast_log(LOG_WARNING, "Spill already exists?!?\n");
1926
		ast_free(p->cidspill);
1926
		ast_free(p->cidspill);
1927
	}
1927
	}
1928

    
   
1928

   
1929
	/*
1929
	/*
1930
	 * SAS: Subscriber Alert Signal, 440Hz for 300ms
1930
	 * SAS: Subscriber Alert Signal, 440Hz for 300ms
1931
	 * CAS: CPE Alert Signal, 2130Hz * 2750Hz sine waves
1931
	 * CAS: CPE Alert Signal, 2130Hz * 2750Hz sine waves
1932
	 */
1932
	 */
1933
	if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4)))
1933
	if (!(p->cidspill = ast_malloc(2400 /* SAS */ + 680 /* CAS */ + READ_SIZE * 4)))
1934
		return -1;
1934
		return -1;
1935
	save_conference(p);
1935
	save_conference(p);
1936
	/* Silence */
1936
	/* Silence */
1937
	memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4);
1937
	memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4);
1938
	if (!p->callwaitrings && p->callwaitingcallerid) {
1938
	if (!p->callwaitrings && p->callwaitingcallerid) {
1939
		ast_gen_cas(p->cidspill, 1, 2400 + 680, ast_format_set(&tmpfmt, AST_LAW(p), 0));
1939
		ast_gen_cas(p->cidspill, 1, 2400 + 680, ast_format_set(&tmpfmt, AST_LAW(p), 0));
1940
		p->callwaitcas = 1;
1940
		p->callwaitcas = 1;
1941
		p->cidlen = 2400 + 680 + READ_SIZE * 4;
1941
		p->cidlen = 2400 + 680 + READ_SIZE * 4;
1942
	} else {
1942
	} else {
1943
		ast_gen_cas(p->cidspill, 1, 2400, ast_format_set(&tmpfmt, AST_LAW(p), 0));
1943
		ast_gen_cas(p->cidspill, 1, 2400, ast_format_set(&tmpfmt, AST_LAW(p), 0));
1944
		p->callwaitcas = 0;
1944
		p->callwaitcas = 0;
1945
		p->cidlen = 2400 + READ_SIZE * 4;
1945
		p->cidlen = 2400 + READ_SIZE * 4;
1946
	}
1946
	}
1947
	p->cidpos = 0;
1947
	p->cidpos = 0;
1948
	send_callerid(p);
1948
	send_callerid(p);
1949

    
   
1949

   
1950
	return 0;
1950
	return 0;
1951
}
1951
}
1952

    
   
1952

   
1953
static int my_send_callerid(void *pvt, int cwcid, struct ast_party_caller *caller)
1953
static int my_send_callerid(void *pvt, int cwcid, struct ast_party_caller *caller)
1954
{
1954
{
1955
	struct dahdi_pvt *p = pvt;
1955
	struct dahdi_pvt *p = pvt;
1956
	struct ast_format tmpfmt;
1956
	struct ast_format tmpfmt;
1957

    
   
1957

   
1958
	ast_debug(2, "Starting cid spill\n");
1958
	ast_debug(2, "Starting cid spill\n");
1959

    
   
1959

   
1960
	if (p->cidspill) {
1960
	if (p->cidspill) {
1961
		ast_log(LOG_WARNING, "cidspill already exists??\n");
1961
		ast_log(LOG_WARNING, "cidspill already exists??\n");
1962
		ast_free(p->cidspill);
1962
		ast_free(p->cidspill);
1963
	}
1963
	}
1964

    
   
1964

   
1965
	if ((p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) {
1965
	if ((p->cidspill = ast_malloc(MAX_CALLERID_SIZE))) {
1966
		if (cwcid == 0) {
1966
		if (cwcid == 0) {
1967
			p->cidlen = ast_callerid_generate(p->cidspill,
1967
			p->cidlen = ast_callerid_generate(p->cidspill,
1968
				caller->id.name.str,
1968
				caller->id.name.str,
1969
				caller->id.number.str,
1969
				caller->id.number.str,
1970
				ast_format_set(&tmpfmt, AST_LAW(p), 0));
1970
				ast_format_set(&tmpfmt, AST_LAW(p), 0));
1971
		} else {
1971
		} else {
1972
			ast_verb(3, "CPE supports Call Waiting Caller*ID.  Sending '%s/%s'\n",
1972
			ast_verb(3, "CPE supports Call Waiting Caller*ID.  Sending '%s/%s'\n",
1973
				caller->id.name.str, caller->id.number.str);
1973
				caller->id.name.str, caller->id.number.str);
1974
			p->callwaitcas = 0;
1974
			p->callwaitcas = 0;
1975
			p->cidcwexpire = 0;
1975
			p->cidcwexpire = 0;
1976
			p->cidlen = ast_callerid_callwaiting_generate(p->cidspill,
1976
			p->cidlen = ast_callerid_callwaiting_generate(p->cidspill,
1977
				caller->id.name.str,
1977
				caller->id.name.str,
1978
				caller->id.number.str,
1978
				caller->id.number.str,
1979
				ast_format_set(&tmpfmt, AST_LAW(p), 0));
1979
				ast_format_set(&tmpfmt, AST_LAW(p), 0));
1980
			p->cidlen += READ_SIZE * 4;
1980
			p->cidlen += READ_SIZE * 4;
1981
		}
1981
		}
1982
		p->cidpos = 0;
1982
		p->cidpos = 0;
1983
		p->cid_suppress_expire = 0;
1983
		p->cid_suppress_expire = 0;
1984
		send_callerid(p);
1984
		send_callerid(p);
1985
	}
1985
	}
1986
	return 0;
1986
	return 0;
1987
}
1987
}
1988

    
   
1988

   
1989
static int my_dsp_reset_and_flush_digits(void *pvt)
1989
static int my_dsp_reset_and_flush_digits(void *pvt)
1990
{
1990
{
1991
	struct dahdi_pvt *p = pvt;
1991
	struct dahdi_pvt *p = pvt;
1992
	if (p->dsp)
1992
	if (p->dsp)
1993
		ast_dsp_digitreset(p->dsp);
1993
		ast_dsp_digitreset(p->dsp);
1994

    
   
1994

   
1995
	return 0;
1995
	return 0;
1996
}
1996
}
1997

    
   
1997

   
1998
static int my_dsp_set_digitmode(void *pvt, enum analog_dsp_digitmode mode)
1998
static int my_dsp_set_digitmode(void *pvt, enum analog_dsp_digitmode mode)
1999
{
1999
{
2000
	struct dahdi_pvt *p = pvt;
2000
	struct dahdi_pvt *p = pvt;
2001

    
   
2001

   
2002
	if (p->channel == CHAN_PSEUDO)
2002
	if (p->channel == CHAN_PSEUDO)
2003
		ast_log(LOG_ERROR, "You have assumed incorrectly sir!\n");
2003
		ast_log(LOG_ERROR, "You have assumed incorrectly sir!\n");
2004

    
   
2004

   
2005
	if (mode == ANALOG_DIGITMODE_DTMF) {
2005
	if (mode == ANALOG_DIGITMODE_DTMF) {
2006
		/* If we do hardware dtmf, no need for a DSP */
2006
		/* If we do hardware dtmf, no need for a DSP */
2007
		if (p->hardwaredtmf) {
2007
		if (p->hardwaredtmf) {
2008
			if (p->dsp) {
2008
			if (p->dsp) {
2009
				ast_dsp_free(p->dsp);
2009
				ast_dsp_free(p->dsp);
2010
				p->dsp = NULL;
2010
				p->dsp = NULL;
2011
			}
2011
			}
2012
			return 0;
2012
			return 0;
2013
		}
2013
		}
2014

    
   
2014

   
2015
		if (!p->dsp) {
2015
		if (!p->dsp) {
2016
			p->dsp = ast_dsp_new();
2016
			p->dsp = ast_dsp_new();
2017
			if (!p->dsp) {
2017
			if (!p->dsp) {
2018
				ast_log(LOG_ERROR, "Unable to allocate DSP\n");
2018
				ast_log(LOG_ERROR, "Unable to allocate DSP\n");
2019
				return -1;
2019
				return -1;
2020
			}
2020
			}
2021
		}
2021
		}
2022

    
   
2022

   
2023
		ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax);
2023
		ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_DTMF | p->dtmfrelax);
2024
	} else if (mode == ANALOG_DIGITMODE_MF) {
2024
	} else if (mode == ANALOG_DIGITMODE_MF) {
2025
		if (!p->dsp) {
2025
		if (!p->dsp) {
2026
			p->dsp = ast_dsp_new();
2026
			p->dsp = ast_dsp_new();
2027
			if (!p->dsp) {
2027
			if (!p->dsp) {
2028
				ast_log(LOG_ERROR, "Unable to allocate DSP\n");
2028
				ast_log(LOG_ERROR, "Unable to allocate DSP\n");
2029
				return -1;
2029
				return -1;
2030
			}
2030
			}
2031
		}
2031
		}
2032
		ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MF | p->dtmfrelax);
2032
		ast_dsp_set_digitmode(p->dsp, DSP_DIGITMODE_MF | p->dtmfrelax);
2033
	}
2033
	}
2034
	return 0;
2034
	return 0;
2035
}
2035
}
2036

    
   
2036

   
2037
static int dahdi_wink(struct dahdi_pvt *p, int index);
2037
static int dahdi_wink(struct dahdi_pvt *p, int index);
2038

    
   
2038

   
2039
static int my_wink(void *pvt, enum analog_sub sub)
2039
static int my_wink(void *pvt, enum analog_sub sub)
2040
{
2040
{
2041
	struct dahdi_pvt *p = pvt;
2041
	struct dahdi_pvt *p = pvt;
2042
	int index = analogsub_to_dahdisub(sub);
2042
	int index = analogsub_to_dahdisub(sub);
2043
	if (index != SUB_REAL) {
2043
	if (index != SUB_REAL) {
2044
		ast_log(LOG_ERROR, "We used a sub other than SUB_REAL (incorrect assumption sir)\n");
2044
		ast_log(LOG_ERROR, "We used a sub other than SUB_REAL (incorrect assumption sir)\n");
2045
	}
2045
	}
2046
	return dahdi_wink(p, index);
2046
	return dahdi_wink(p, index);
2047
}
2047
}
2048

    
   
2048

   
2049
static void wakeup_sub(struct dahdi_pvt *p, int a);
2049
static void wakeup_sub(struct dahdi_pvt *p, int a);
2050

    
   
2050

   
2051
static int reset_conf(struct dahdi_pvt *p);
2051
static int reset_conf(struct dahdi_pvt *p);
2052

    
   
2052

   
2053
static inline int dahdi_confmute(struct dahdi_pvt *p, int muted);
2053
static inline int dahdi_confmute(struct dahdi_pvt *p, int muted);
2054

    
   
2054

   
2055
static void my_handle_dtmf(void *pvt, struct ast_channel *ast, enum analog_sub analog_index, struct ast_frame **dest)
2055
static void my_handle_dtmf(void *pvt, struct ast_channel *ast, enum analog_sub analog_index, struct ast_frame **dest)
2056
{
2056
{
2057
	struct ast_frame *f = *dest;
2057
	struct ast_frame *f = *dest;
2058
	struct dahdi_pvt *p = pvt;
2058
	struct dahdi_pvt *p = pvt;
2059
	int idx = analogsub_to_dahdisub(analog_index);
2059
	int idx = analogsub_to_dahdisub(analog_index);
2060

    
   
2060

   
2061
	ast_debug(1, "%s DTMF digit: 0x%02X '%c' on %s\n",
2061
	ast_debug(1, "%s DTMF digit: 0x%02X '%c' on %s\n",
2062
		f->frametype == AST_FRAME_DTMF_BEGIN ? "Begin" : "End",
2062
		f->frametype == AST_FRAME_DTMF_BEGIN ? "Begin" : "End",
2063
		f->subclass.integer, f->subclass.integer, ast_channel_name(ast));
2063
		f->subclass.integer, f->subclass.integer, ast_channel_name(ast));
2064

    
   
2064

   
2065
	if (f->subclass.integer == 'f') {
2065
	if (f->subclass.integer == 'f') {
2066
		if (f->frametype == AST_FRAME_DTMF_END) {
2066
		if (f->frametype == AST_FRAME_DTMF_END) {
2067
			/* Fax tone -- Handle and return NULL */
2067
			/* Fax tone -- Handle and return NULL */
2068
			if ((p->callprogress & CALLPROGRESS_FAX) && !p->faxhandled) {
2068
			if ((p->callprogress & CALLPROGRESS_FAX) && !p->faxhandled) {
2069
				/* If faxbuffers are configured, use them for the fax transmission */
2069
				/* If faxbuffers are configured, use them for the fax transmission */
2070
				if (p->usefaxbuffers && !p->bufferoverrideinuse) {
2070
				if (p->usefaxbuffers && !p->bufferoverrideinuse) {
2071
					struct dahdi_bufferinfo bi = {
2071
					struct dahdi_bufferinfo bi = {
2072
						.txbufpolicy = p->faxbuf_policy,
2072
						.txbufpolicy = p->faxbuf_policy,
2073
						.bufsize = p->bufsize,
2073
						.bufsize = p->bufsize,
2074
						.numbufs = p->faxbuf_no
2074
						.numbufs = p->faxbuf_no
2075
					};
2075
					};
2076
					int res;
2076
					int res;
2077

    
   
2077

   
2078
					if ((res = ioctl(p->subs[idx].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
2078
					if ((res = ioctl(p->subs[idx].dfd, DAHDI_SET_BUFINFO, &bi)) < 0) {
2079
						ast_log(LOG_WARNING, "Channel '%s' unable to set buffer policy, reason: %s\n", ast_channel_name(ast), strerror(errno));
2079
						ast_log(LOG_WARNING, "Channel '%s' unable to set buffer policy, reason: %s\n", ast_channel_name(ast), strerror(errno));
2080
					} else {
2080
					} else {
2081
						p->bufferoverrideinuse = 1;
2081
						p->bufferoverrideinuse = 1;
2082
					}
2082
					}
2083
				}
2083
				}
2084
				p->faxhandled = 1;
2084
				p->faxhandled = 1;
2085
				if (p->dsp) {
2085
				if (p->dsp) {
2086
					p->dsp_features &= ~DSP_FEATURE_FAX_DETECT;
2086
					p->dsp_features &= ~DSP_FEATURE_FAX_DETECT;
2087
					ast_dsp_set_features(p->dsp, p->dsp_features);
2087
					ast_dsp_set_features(p->dsp, p->dsp_features);
2088
					ast_debug(1, "Disabling FAX tone detection on %s after tone received\n", ast_channel_name(ast));
2088
					ast_debug(1, "Disabling FAX tone detection on %s after tone received\n", ast_channel_name(ast));
2089
				}
2089
				}
2090
				if (strcmp(ast->exten, "fax")) {
2090
				if (strcmp(ast->exten, "fax")) {
2091
					const char *target_context = S_OR(ast->macrocontext, ast->context);
2091
					const char *target_context = S_OR(ast->macrocontext, ast->context);
2092

    
   
2092

   
2093
					/* We need to unlock 'ast' here because ast_exists_extension has the
2093
					/* We need to unlock 'ast' here because ast_exists_extension has the
2094
					 * potential to start autoservice on the channel. Such action is prone
2094
					 * potential to start autoservice on the channel. Such action is prone
2095
					 * to deadlock.
2095
					 * to deadlock.
2096
					 */
2096
					 */
2097
					ast_mutex_unlock(&p->lock);
2097
					ast_mutex_unlock(&p->lock);
2098
					ast_channel_unlock(ast);
2098
					ast_channel_unlock(ast);
2099
					if (ast_exists_extension(ast, target_context, "fax", 1,
2099
					if (ast_exists_extension(ast, target_context, "fax", 1,
2100
						S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, NULL))) {
2100
						S_COR(ast->caller.id.number.valid, ast->caller.id.number.str, NULL))) {
2101
						ast_channel_lock(ast);
2101
						ast_channel_lock(ast);
2102
						ast_mutex_lock(&p->lock);
2102
						ast_mutex_lock(&p->lock);
2103
						ast_verb(3, "Redirecting %s to fax extension\n", ast_channel_name(ast));
2103
						ast_verb(3, "Redirecting %s to fax extension\n", ast_channel_name(ast));
2104
						/* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
2104
						/* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
2105
						pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten);
2105
						pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten);
2106
						if (ast_async_goto(ast, target_context, "fax", 1))
2106
						if (ast_async_goto(ast, target_context, "fax", 1))
2107
							ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast_channel_name(ast), target_context);
2107
							ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast_channel_name(ast), target_context);
2108
					} else {
2108
					} else {
2109
						ast_channel_lock(ast);
2109
						ast_channel_lock(ast);
2110
						ast_mutex_lock(&p->lock);
2110
						ast_mutex_lock(&p->lock);
2111
						ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n");
2111
						ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n");
2112
					}
2112
					}
2113
				} else {
2113
				} else {
2114
					ast_debug(1, "Already in a fax extension, not redirecting\n");
2114
					ast_debug(1, "Already in a fax extension, not redirecting\n");
2115
				}
2115
				}
2116
			} else {
2116
			} else {
2117
				ast_debug(1, "Fax already handled\n");
2117
				ast_debug(1, "Fax already handled\n");
2118
			}
2118
			}
2119
			dahdi_confmute(p, 0);
2119
			dahdi_confmute(p, 0);
2120
		}
2120
		}
2121
		p->subs[idx].f.frametype = AST_FRAME_NULL;
2121
		p->subs[idx].f.frametype = AST_FRAME_NULL;
2122
		p->subs[idx].f.subclass.integer = 0;
2122
		p->subs[idx].f.subclass.integer = 0;
2123
		*dest = &p->subs[idx].f;
2123
		*dest = &p->subs[idx].f;
2124
	}
2124
	}
2125
}
2125
}
2126

    
   
2126

   
2127
static void my_lock_private(void *pvt)
2127
static void my_lock_private(void *pvt)
2128
{
2128
{
2129
	struct dahdi_pvt *p = pvt;
2129
	struct dahdi_pvt *p = pvt;
2130
	ast_mutex_lock(&p->lock);
2130
	ast_mutex_lock(&p->lock);
2131
}
2131
}
2132

    
   
2132

   
2133
static void my_unlock_private(void *pvt)
2133
static void my_unlock_private(void *pvt)
2134
{
2134
{
2135
	struct dahdi_pvt *p = pvt;
2135
	struct dahdi_pvt *p = pvt;
2136
	ast_mutex_unlock(&p->lock);
2136
	ast_mutex_unlock(&p->lock);
2137
}
2137
}
2138

    
   
2138

   
2139
static void my_deadlock_avoidance_private(void *pvt)
2139
static void my_deadlock_avoidance_private(void *pvt)
2140
{
2140
{
2141
	struct dahdi_pvt *p = pvt;
2141
	struct dahdi_pvt *p = pvt;
2142

    
   
2142

   
2143
	DEADLOCK_AVOIDANCE(&p->lock);
2143
	DEADLOCK_AVOIDANCE(&p->lock);
2144
}
2144
}
2145

    
   
2145

   
2146
/*!
2146
/*!
2147
 * \internal
2147
 * \internal
2148
 * \brief Post an AMI DAHDI channel association event.
2148
 * \brief Post an AMI DAHDI channel association event.
2149
 * \since 1.8
2149
 * \since 1.8
2150
 *
2150
 *
2151
 * \param p DAHDI private pointer
2151
 * \param p DAHDI private pointer
2152
 * \param chan Channel associated with the private pointer
2152
 * \param chan Channel associated with the private pointer
2153
 *
2153
 *
2154
 * \return Nothing
2154
 * \return Nothing
2155
 */
2155
 */
2156
static void dahdi_ami_channel_event(struct dahdi_pvt *p, struct ast_channel *chan)
2156
static void dahdi_ami_channel_event(struct dahdi_pvt *p, struct ast_channel *chan)
2157
{
2157
{
2158
	char ch_name[20];
2158
	char ch_name[20];
2159

    
   
2159

   
2160
	if (p->channel < CHAN_PSEUDO) {
2160
	if (p->channel < CHAN_PSEUDO) {
2161
		/* No B channel */
2161
		/* No B channel */
2162
		snprintf(ch_name, sizeof(ch_name), "no-media (%d)", p->channel);
2162
		snprintf(ch_name, sizeof(ch_name), "no-media (%d)", p->channel);
2163
	} else if (p->channel == CHAN_PSEUDO) {
2163
	} else if (p->channel == CHAN_PSEUDO) {
2164
		/* Pseudo channel */
2164
		/* Pseudo channel */
2165
		strcpy(ch_name, "pseudo");
2165
		strcpy(ch_name, "pseudo");
2166
	} else {
2166
	} else {
2167
		/* Real channel */
2167
		/* Real channel */
2168
		snprintf(ch_name, sizeof(ch_name), "%d", p->channel);
2168
		snprintf(ch_name, sizeof(ch_name), "%d", p->channel);
2169
	}
2169
	}
2170
	ast_manager_event(chan, EVENT_FLAG_CALL, "DAHDIChannel",
2170
	ast_manager_event(chan, EVENT_FLAG_CALL, "DAHDIChannel",
2171
		"Channel: %s\r\n"
2171
		"Channel: %s\r\n"
2172
		"Uniqueid: %s\r\n"
2172
		"Uniqueid: %s\r\n"
2173
		"DAHDISpan: %d\r\n"
2173
		"DAHDISpan: %d\r\n"
2174
		"DAHDIChannel: %s\r\n",
2174
		"DAHDIChannel: %s\r\n",
2175
		ast_channel_name(chan),
2175
		ast_channel_name(chan),
2176
		ast_channel_uniqueid(chan),
2176
		ast_channel_uniqueid(chan),
2177
		p->span,
2177
		p->span,
2178
		ch_name);
2178
		ch_name);
2179
}
2179
}
2180

    
   
2180

   
2181
#ifdef HAVE_PRI
2181
#ifdef HAVE_PRI
2182
/*!
2182
/*!
2183
 * \internal
2183
 * \internal
2184
 * \brief Post an AMI DAHDI channel association event.
2184
 * \brief Post an AMI DAHDI channel association event.
2185
 * \since 1.8
2185
 * \since 1.8
2186
 *
2186
 *
2187
 * \param pvt DAHDI private pointer
2187
 * \param pvt DAHDI private pointer
2188
 * \param chan Channel associated with the private pointer
2188
 * \param chan Channel associated with the private pointer
2189
 *
2189
 *
2190
 * \return Nothing
2190
 * \return Nothing
2191
 */
2191
 */
2192
static void my_ami_channel_event(void *pvt, struct ast_channel *chan)
2192
static void my_ami_channel_event(void *pvt, struct ast_channel *chan)
2193
{
2193
{
2194
	struct dahdi_pvt *p = pvt;
2194
	struct dahdi_pvt *p = pvt;
2195

    
   
2195

   
2196
	dahdi_ami_channel_event(p, chan);
2196
	dahdi_ami_channel_event(p, chan);
2197
}
2197
}
2198
#endif
2198
#endif
2199

    
   
2199

   
2200
/* linear_mode = 0 - turn linear mode off, >0 - turn linear mode on
2200
/* linear_mode = 0 - turn linear mode off, >0 - turn linear mode on
2201
* 	returns the last value of the linear setting 
2201
* 	returns the last value of the linear setting 
2202
*/ 
2202
*/ 
2203
static int my_set_linear_mode(void *pvt, enum analog_sub sub, int linear_mode)
2203
static int my_set_linear_mode(void *pvt, enum analog_sub sub, int linear_mode)
2204
{
2204
{
2205
	struct dahdi_pvt *p = pvt;
2205
	struct dahdi_pvt *p = pvt;
2206
	int oldval;
2206
	int oldval;
2207
	int idx = analogsub_to_dahdisub(sub);
2207
	int idx = analogsub_to_dahdisub(sub);
2208
	
2208
	
2209
	dahdi_setlinear(p->subs[idx].dfd, linear_mode);
2209
	dahdi_setlinear(p->subs[idx].dfd, linear_mode);
2210
	oldval = p->subs[idx].linear;
2210
	oldval = p->subs[idx].linear;
2211
	p->subs[idx].linear = linear_mode ? 1 : 0;
2211
	p->subs[idx].linear = linear_mode ? 1 : 0;
2212
	return oldval;
2212
	return oldval;
2213
}
2213
}
2214

    
   
2214

   
2215
static void my_set_inthreeway(void *pvt, enum analog_sub sub, int inthreeway)
2215
static void my_set_inthreeway(void *pvt, enum analog_sub sub, int inthreeway)
2216
{
2216
{
2217
	struct dahdi_pvt *p = pvt;
2217
	struct dahdi_pvt *p = pvt;
2218
	int idx = analogsub_to_dahdisub(sub);
2218
	int idx = analogsub_to_dahdisub(sub);
2219

    
   
2219

   
2220
	p->subs[idx].inthreeway = inthreeway;
2220
	p->subs[idx].inthreeway = inthreeway;
2221
}
2221
}
2222

    
   
2222

   
2223
static int get_alarms(struct dahdi_pvt *p);
2223
static int get_alarms(struct dahdi_pvt *p);
2224
static void handle_alarms(struct dahdi_pvt *p, int alms);
2224
static void handle_alarms(struct dahdi_pvt *p, int alms);
2225
static void my_get_and_handle_alarms(void *pvt)
2225
static void my_get_and_handle_alarms(void *pvt)
2226
{
2226
{
2227
	int res;
2227
	int res;
2228
	struct dahdi_pvt *p = pvt;
2228
	struct dahdi_pvt *p = pvt;
2229

    
   
2229

   
2230
	res = get_alarms(p);
2230
	res = get_alarms(p);
2231
	handle_alarms(p, res);
2231
	handle_alarms(p, res);
2232
}
2232
}
2233

    
   
2233

   
2234
static void *my_get_sigpvt_bridged_channel(struct ast_channel *chan)
2234
static void *my_get_sigpvt_bridged_channel(struct ast_channel *chan)
2235
{
2235
{
2236
	struct dahdi_pvt *p = ast_bridged_channel(chan)->tech_pvt;
2236
	struct dahdi_pvt *p = ast_bridged_channel(chan)->tech_pvt;
2237
	if (p)
2237
	if (p)
2238
		return p->sig_pvt;
2238
		return p->sig_pvt;
2239
	else
2239
	else
2240
		return NULL;
2240
		return NULL;
2241
}
2241
}
2242

    
   
2242

   
2243
static int my_get_sub_fd(void *pvt, enum analog_sub sub)
2243
static int my_get_sub_fd(void *pvt, enum analog_sub sub)
2244
{
2244
{
2245
	struct dahdi_pvt *p = pvt;
2245
	struct dahdi_pvt *p = pvt;
2246
	int dahdi_sub = analogsub_to_dahdisub(sub);
2246
	int dahdi_sub = analogsub_to_dahdisub(sub);
2247
	return p->subs[dahdi_sub].dfd;
2247
	return p->subs[dahdi_sub].dfd;
2248
}
2248
}
2249

    
   
2249

   
2250
static void my_set_cadence(void *pvt, int *cidrings, struct ast_channel *ast)
2250
static void my_set_cadence(void *pvt, int *cidrings, struct ast_channel *ast)
2251
{
2251
{
2252
	struct dahdi_pvt *p = pvt;
2252
	struct dahdi_pvt *p = pvt;
2253

    
   
2253

   
2254
	/* Choose proper cadence */
2254
	/* Choose proper cadence */
2255
	if ((p->distinctivering > 0) && (p->distinctivering <= num_cadence)) {
2255
	if ((p->distinctivering > 0) && (p->distinctivering <= num_cadence)) {
2256
		if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, &cadences[p->distinctivering - 1]))
2256
		if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, &cadences[p->distinctivering - 1]))
2257
			ast_log(LOG_WARNING, "Unable to set distinctive ring cadence %d on '%s': %s\n", p->distinctivering, ast_channel_name(ast), strerror(errno));
2257
			ast_log(LOG_WARNING, "Unable to set distinctive ring cadence %d on '%s': %s\n", p->distinctivering, ast_channel_name(ast), strerror(errno));
2258
		*cidrings = cidrings[p->distinctivering - 1];
2258
		*cidrings = cidrings[p->distinctivering - 1];
2259
	} else {
2259
	} else {
2260
		if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, NULL))
2260
		if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETCADENCE, NULL))
2261
			ast_log(LOG_WARNING, "Unable to reset default ring on '%s': %s\n", ast_channel_name(ast), strerror(errno));
2261
			ast_log(LOG_WARNING, "Unable to reset default ring on '%s': %s\n", ast_channel_name(ast), strerror(errno));
2262
		*cidrings = p->sendcalleridafter;
2262
		*cidrings = p->sendcalleridafter;
2263
	}
2263
	}
2264
}
2264
}
2265

    
   
2265

   
2266
static void my_set_alarm(void *pvt, int in_alarm)
2266
static void my_set_alarm(void *pvt, int in_alarm)
2267
{
2267
{
2268
	struct dahdi_pvt *p = pvt;
2268
	struct dahdi_pvt *p = pvt;
2269

    
   
2269

   
2270
	p->inalarm = in_alarm;
2270
	p->inalarm = in_alarm;
2271
}
2271
}
2272

    
   
2272

   
2273
static void my_set_dialing(void *pvt, int is_dialing)
2273
static void my_set_dialing(void *pvt, int is_dialing)
2274
{
2274
{
2275
	struct dahdi_pvt *p = pvt;
2275
	struct dahdi_pvt *p = pvt;
2276

    
   
2276

   
2277
	p->dialing = is_dialing;
2277
	p->dialing = is_dialing;
2278
}
2278
}
2279

    
   
2279

   

    
   
2280
static void my_set_outgoing(void *pvt, int is_outgoing)

    
   
2281
{

    
   
2282
	struct dahdi_pvt *p = pvt;

    
   
2283

   

    
   
2284
	ast_log(LOG_WARNING, "ALEC p->outgoing(%d) = %d\n", p->outgoing, is_outgoing);

    
   
2285
	p->outgoing = is_outgoing;

    
   
2286
}

    
   
2287

   
2280
#if defined(HAVE_PRI) || defined(HAVE_SS7)
2288
#if defined(HAVE_PRI) || defined(HAVE_SS7)
2281
static void my_set_digital(void *pvt, int is_digital)
2289
static void my_set_digital(void *pvt, int is_digital)
2282
{
2290
{
2283
	struct dahdi_pvt *p = pvt;
2291
	struct dahdi_pvt *p = pvt;
2284

    
   
2292

   
2285
	p->digital = is_digital;
2293
	p->digital = is_digital;
2286
}
2294
}
2287
#endif	/* defined(HAVE_PRI) || defined(HAVE_SS7) */
2295
#endif	/* defined(HAVE_PRI) || defined(HAVE_SS7) */
2288

    
   
2296

   
2289
#if defined(HAVE_SS7)
2297
#if defined(HAVE_SS7)
2290
static void my_set_inservice(void *pvt, int is_inservice)
2298
static void my_set_inservice(void *pvt, int is_inservice)
2291
{
2299
{
2292
	struct dahdi_pvt *p = pvt;
2300
	struct dahdi_pvt *p = pvt;
2293

    
   
2301

   
2294
	p->inservice = is_inservice;
2302
	p->inservice = is_inservice;
2295
}
2303
}
2296
#endif	/* defined(HAVE_SS7) */
2304
#endif	/* defined(HAVE_SS7) */
2297

    
   
2305

   
2298
#if defined(HAVE_SS7)
2306
#if defined(HAVE_SS7)
2299
static void my_set_locallyblocked(void *pvt, int is_blocked)
2307
static void my_set_locallyblocked(void *pvt, int is_blocked)
2300
{
2308
{
2301
	struct dahdi_pvt *p = pvt;
2309
	struct dahdi_pvt *p = pvt;
2302

    
   
2310

   
2303
	p->locallyblocked = is_blocked;
2311
	p->locallyblocked = is_blocked;
2304
}
2312
}
2305
#endif	/* defined(HAVE_SS7) */
2313
#endif	/* defined(HAVE_SS7) */
2306

    
   
2314

   
2307
#if defined(HAVE_SS7)
2315
#if defined(HAVE_SS7)
2308
static void my_set_remotelyblocked(void *pvt, int is_blocked)
2316
static void my_set_remotelyblocked(void *pvt, int is_blocked)
2309
{
2317
{
2310
	struct dahdi_pvt *p = pvt;
2318
	struct dahdi_pvt *p = pvt;
2311

    
   
2319

   
2312
	p->remotelyblocked = is_blocked;
2320
	p->remotelyblocked = is_blocked;
2313
}
2321
}
2314
#endif	/* defined(HAVE_SS7) */
2322
#endif	/* defined(HAVE_SS7) */
2315

    
   
2323

   
2316
static void my_set_ringtimeout(void *pvt, int ringt)
2324
static void my_set_ringtimeout(void *pvt, int ringt)
2317
{
2325
{
2318
	struct dahdi_pvt *p = pvt;
2326
	struct dahdi_pvt *p = pvt;
2319
	p->ringt = ringt;
2327
	p->ringt = ringt;
2320
}
2328
}
2321

    
   
2329

   
2322
static void my_set_waitingfordt(void *pvt, struct ast_channel *ast)
2330
static void my_set_waitingfordt(void *pvt, struct ast_channel *ast)
2323
{
2331
{
2324
	struct dahdi_pvt *p = pvt;
2332
	struct dahdi_pvt *p = pvt;
2325

    
   
2333

   
2326
	if (p->waitfordialtone && CANPROGRESSDETECT(p) && p->dsp) {
2334
	if (p->waitfordialtone && CANPROGRESSDETECT(p) && p->dsp) {
2327
		ast_debug(1, "Defer dialing for %dms or dialtone\n", p->waitfordialtone);
2335
		ast_debug(1, "Defer dialing for %dms or dialtone\n", p->waitfordialtone);
2328
		gettimeofday(&p->waitingfordt, NULL);
2336
		gettimeofday(&p->waitingfordt, NULL);
2329
		ast_setstate(ast, AST_STATE_OFFHOOK);
2337
		ast_setstate(ast, AST_STATE_OFFHOOK);
2330
	}
2338
	}
2331
}
2339
}
2332

    
   
2340

   
2333
static int my_check_waitingfordt(void *pvt)
2341
static int my_check_waitingfordt(void *pvt)
2334
{
2342
{
2335
	struct dahdi_pvt *p = pvt;
2343
	struct dahdi_pvt *p = pvt;
2336

    
   
2344

   
2337
	if (p->waitingfordt.tv_usec) {
2345
	if (p->waitingfordt.tv_usec) {
2338
		return 1;
2346
		return 1;
2339
	}
2347
	}
2340

    
   
2348

   
2341
	return 0;
2349
	return 0;
2342
}
2350
}
2343

    
   
2351

   
2344
static void my_set_confirmanswer(void *pvt, int flag)
2352
static void my_set_confirmanswer(void *pvt, int flag)
2345
{
2353
{
2346
	struct dahdi_pvt *p = pvt;
2354
	struct dahdi_pvt *p = pvt;
2347
	p->confirmanswer = flag;
2355
	p->confirmanswer = flag;
2348
}
2356
}
2349

    
   
2357

   
2350
static int my_check_confirmanswer(void *pvt)
2358
static int my_check_confirmanswer(void *pvt)
2351
{
2359
{
2352
	struct dahdi_pvt *p = pvt;
2360
	struct dahdi_pvt *p = pvt;
2353
	if (p->confirmanswer) {
2361
	if (p->confirmanswer) {
2354
		return 1;
2362
		return 1;
2355
	}
2363
	}
2356

    
   
2364

   
2357
	return 0;
2365
	return 0;
2358
}
2366
}
2359

    
   
2367

   
2360
static void my_set_callwaiting(void *pvt, int callwaiting_enable)
2368
static void my_set_callwaiting(void *pvt, int callwaiting_enable)
2361
{
2369
{
2362
	struct dahdi_pvt *p = pvt;
2370
	struct dahdi_pvt *p = pvt;
2363

    
   
2371

   
2364
	p->callwaiting = callwaiting_enable;
2372
	p->callwaiting = callwaiting_enable;
2365
}
2373
}
2366

    
   
2374

   
2367
static void my_cancel_cidspill(void *pvt)
2375
static void my_cancel_cidspill(void *pvt)
2368
{
2376
{
2369
	struct dahdi_pvt *p = pvt;
2377
	struct dahdi_pvt *p = pvt;
2370

    
   
2378

   
2371
	ast_free(p->cidspill);
2379
	ast_free(p->cidspill);
2372
	p->cidspill = NULL;
2380
	p->cidspill = NULL;
2373
	restore_conference(p);
2381
	restore_conference(p);
2374
}
2382
}
2375

    
   
2383

   
2376
static int my_confmute(void *pvt, int mute)
2384
static int my_confmute(void *pvt, int mute)
2377
{
2385
{
2378
	struct dahdi_pvt *p = pvt;
2386
	struct dahdi_pvt *p = pvt;
2379
	return dahdi_confmute(p, mute);
2387
	return dahdi_confmute(p, mute);
2380
}
2388
}
2381

    
   
2389

   
2382
static void my_set_pulsedial(void *pvt, int flag)
2390
static void my_set_pulsedial(void *pvt, int flag)
2383
{
2391
{
2384
	struct dahdi_pvt *p = pvt;
2392
	struct dahdi_pvt *p = pvt;
2385
	p->pulsedial = flag;
2393
	p->pulsedial = flag;
2386
}
2394
}
2387

    
   
2395

   
2388
static void my_set_new_owner(void *pvt, struct ast_channel *new_owner)
2396
static void my_set_new_owner(void *pvt, struct ast_channel *new_owner)
2389
{
2397
{
2390
	struct dahdi_pvt *p = pvt;
2398
	struct dahdi_pvt *p = pvt;
2391

    
   
2399

   
2392
	p->owner = new_owner;
2400
	p->owner = new_owner;
2393
}
2401
}
2394

    
   
2402

   
2395
static const char *my_get_orig_dialstring(void *pvt)
2403
static const char *my_get_orig_dialstring(void *pvt)
2396
{
2404
{
2397
	struct dahdi_pvt *p = pvt;
2405
	struct dahdi_pvt *p = pvt;
2398

    
   
2406

   
2399
	return p->dialstring;
2407
	return p->dialstring;
2400
}
2408
}
2401

    
   
2409

   
2402
static void my_increase_ss_count(void)
2410
static void my_increase_ss_count(void)
2403
{
2411
{
2404
	ast_mutex_lock(&ss_thread_lock);
2412
	ast_mutex_lock(&ss_thread_lock);
2405
	ss_thread_count++;
2413
	ss_thread_count++;
2406
	ast_mutex_unlock(&ss_thread_lock);
2414
	ast_mutex_unlock(&ss_thread_lock);
2407
}
2415
}
2408

    
   
2416

   
2409
static void my_decrease_ss_count(void)
2417
static void my_decrease_ss_count(void)
2410
{
2418
{
2411
	ast_mutex_lock(&ss_thread_lock);
2419
	ast_mutex_lock(&ss_thread_lock);
2412
	ss_thread_count--;
2420
	ss_thread_count--;
2413
	ast_cond_signal(&ss_thread_complete);
2421
	ast_cond_signal(&ss_thread_complete);
2414
	ast_mutex_unlock(&ss_thread_lock);
2422
	ast_mutex_unlock(&ss_thread_lock);
2415
}
2423
}
2416

    
   
2424

   
2417
static void my_all_subchannels_hungup(void *pvt)
2425
static void my_all_subchannels_hungup(void *pvt)
2418
{
2426
{
2419
	struct dahdi_pvt *p = pvt;
2427
	struct dahdi_pvt *p = pvt;
2420
	int res, law;
2428
	int res, law;
2421

    
   
2429

   
2422
	p->faxhandled = 0;
2430
	p->faxhandled = 0;
2423
	p->didtdd = 0;
2431
	p->didtdd = 0;
2424

    
   
2432

   
2425
	if (p->dsp) {
2433
	if (p->dsp) {
2426
		ast_dsp_free(p->dsp);
2434
		ast_dsp_free(p->dsp);
2427
		p->dsp = NULL;
2435
		p->dsp = NULL;
2428
	}
2436
	}
2429

    
   
2437

   
2430
	p->law = p->law_default;
2438
	p->law = p->law_default;
2431
	law = p->law_default;
2439
	law = p->law_default;
2432
	res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law);
2440
	res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETLAW, &law);
2433
	if (res < 0)
2441
	if (res < 0)
2434
		ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n", p->channel, strerror(errno));
2442
		ast_log(LOG_WARNING, "Unable to set law on channel %d to default: %s\n", p->channel, strerror(errno));
2435

    
   
2443

   
2436
	dahdi_setlinear(p->subs[SUB_REAL].dfd, 0);
2444
	dahdi_setlinear(p->subs[SUB_REAL].dfd, 0);
2437

    
   
2445

   
2438
#if 1
2446
#if 1
2439
	{
2447
	{
2440
	int i;
2448
	int i;
2441
	p->owner = NULL;
2449
	p->owner = NULL;
2442
	/* Cleanup owners here */
2450
	/* Cleanup owners here */
2443
	for (i = 0; i < 3; i++) {
2451
	for (i = 0; i < 3; i++) {
2444
		p->subs[i].owner = NULL;
2452
		p->subs[i].owner = NULL;
2445
	}
2453
	}
2446
	}
2454
	}
2447
#endif
2455
#endif
2448

    
   
2456

   
2449
	reset_conf(p);
2457
	reset_conf(p);
2450
	if (num_restart_pending == 0) {
2458
	if (num_restart_pending == 0) {
2451
		restart_monitor();
2459
		restart_monitor();
2452
	}
2460
	}
2453
}
2461
}
2454

    
   
2462

   
2455
static int conf_del(struct dahdi_pvt *p, struct dahdi_subchannel *c, int index);
2463
static int conf_del(struct dahdi_pvt *p, struct dahdi_subchannel *c, int index);
2456

    
   
2464

   
2457
static int my_conf_del(void *pvt, enum analog_sub sub)
2465
static int my_conf_del(void *pvt, enum analog_sub sub)
2458
{
2466
{
2459
	struct dahdi_pvt *p = pvt;
2467
	struct dahdi_pvt *p = pvt;
2460
	int x = analogsub_to_dahdisub(sub);
2468
	int x = analogsub_to_dahdisub(sub);
2461

    
   
2469

   
2462
	return conf_del(p, &p->subs[x], x);
2470
	return conf_del(p, &p->subs[x], x);
2463
}
2471
}
2464

    
   
2472

   
2465
static int conf_add(struct dahdi_pvt *p, struct dahdi_subchannel *c, int index, int slavechannel);
2473
static int conf_add(struct dahdi_pvt *p, struct dahdi_subchannel *c, int index, int slavechannel);
2466

    
   
2474

   
2467
static int my_conf_add(void *pvt, enum analog_sub sub)
2475
static int my_conf_add(void *pvt, enum analog_sub sub)
2468
{
2476
{
2469
	struct dahdi_pvt *p = pvt;
2477
	struct dahdi_pvt *p = pvt;
2470
	int x = analogsub_to_dahdisub(sub);
2478
	int x = analogsub_to_dahdisub(sub);
2471

    
   
2479

   
2472
	return conf_add(p, &p->subs[x], x, 0);
2480
	return conf_add(p, &p->subs[x], x, 0);
2473
}
2481
}
2474

    
   
2482

   
2475
static int isslavenative(struct dahdi_pvt *p, struct dahdi_pvt **out);
2483
static int isslavenative(struct dahdi_pvt *p, struct dahdi_pvt **out);
2476

    
   
2484

   
2477
static int my_complete_conference_update(void *pvt, int needconference)
2485
static int my_complete_conference_update(void *pvt, int needconference)
2478
{
2486
{
2479
	struct dahdi_pvt *p = pvt;
2487
	struct dahdi_pvt *p = pvt;
2480
	int needconf = needconference;
2488
	int needconf = needconference;
2481
	int x;
2489
	int x;
2482
	int useslavenative;
2490
	int useslavenative;
2483
	struct dahdi_pvt *slave = NULL;
2491
	struct dahdi_pvt *slave = NULL;
2484

    
   
2492

   
2485
	useslavenative = isslavenative(p, &slave);
2493
	useslavenative = isslavenative(p, &slave);
2486

    
   
2494

   
2487
	/* If we have a slave, add him to our conference now. or DAX
2495
	/* If we have a slave, add him to our conference now. or DAX
2488
	   if this is slave native */
2496
	   if this is slave native */
2489
	for (x = 0; x < MAX_SLAVES; x++) {
2497
	for (x = 0; x < MAX_SLAVES; x++) {
2490
		if (p->slaves[x]) {
2498
		if (p->slaves[x]) {
2491
			if (useslavenative)
2499
			if (useslavenative)
2492
				conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p));
2500
				conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p));
2493
			else {
2501
			else {
2494
				conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0);
2502
				conf_add(p, &p->slaves[x]->subs[SUB_REAL], SUB_REAL, 0);
2495
				needconf++;
2503
				needconf++;
2496
			}
2504
			}
2497
		}
2505
		}
2498
	}
2506
	}
2499
	/* If we're supposed to be in there, do so now */
2507
	/* If we're supposed to be in there, do so now */
2500
	if (p->inconference && !p->subs[SUB_REAL].inthreeway) {
2508
	if (p->inconference && !p->subs[SUB_REAL].inthreeway) {
2501
		if (useslavenative)
2509
		if (useslavenative)
2502
			conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave));
2510
			conf_add(p, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(slave));
2503
		else {
2511
		else {
2504
			conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0);
2512
			conf_add(p, &p->subs[SUB_REAL], SUB_REAL, 0);
2505
			needconf++;
2513
			needconf++;
2506
		}
2514
		}
2507
	}
2515
	}
2508
	/* If we have a master, add ourselves to his conference */
2516
	/* If we have a master, add ourselves to his conference */
2509
	if (p->master) {
2517
	if (p->master) {
2510
		if (isslavenative(p->master, NULL)) {
2518
		if (isslavenative(p->master, NULL)) {
2511
			conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p->master));
2519
			conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, GET_CHANNEL(p->master));
2512
		} else {
2520
		} else {
2513
			conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0);
2521
			conf_add(p->master, &p->subs[SUB_REAL], SUB_REAL, 0);
2514
		}
2522
		}
2515
	}
2523
	}
2516
	if (!needconf) {
2524
	if (!needconf) {
2517
		/* Nobody is left (or should be left) in our conference.
2525
		/* Nobody is left (or should be left) in our conference.
2518
		   Kill it. */
2526
		   Kill it. */
2519
		p->confno = -1;
2527
		p->confno = -1;
2520
	}
2528
	}
2521

    
   
2529

   
2522
	return 0;
2530
	return 0;
2523
}
2531
}
2524

    
   
2532

   
2525
static int check_for_conference(struct dahdi_pvt *p);
2533
static int check_for_conference(struct dahdi_pvt *p);
2526

    
   
2534

   
2527
static int my_check_for_conference(void *pvt)
2535
static int my_check_for_conference(void *pvt)
2528
{
2536
{
2529
	struct dahdi_pvt *p = pvt;
2537
	struct dahdi_pvt *p = pvt;
2530
	return check_for_conference(p);
2538
	return check_for_conference(p);
2531
}
2539
}
2532

    
   
2540

   
2533
static void my_swap_subchannels(void *pvt, enum analog_sub a, struct ast_channel *ast_a,  enum analog_sub b, struct ast_channel *ast_b)
2541
static void my_swap_subchannels(void *pvt, enum analog_sub a, struct ast_channel *ast_a,  enum analog_sub b, struct ast_channel *ast_b)
2534
{
2542
{
2535
	struct dahdi_pvt *p = pvt;
2543
	struct dahdi_pvt *p = pvt;
2536
	int da, db;
2544
	int da, db;
2537
	int tchan;
2545
	int tchan;
2538
	int tinthreeway;
2546
	int tinthreeway;
2539

    
   
2547

   
2540
	da = analogsub_to_dahdisub(a);
2548
	da = analogsub_to_dahdisub(a);
2541
	db = analogsub_to_dahdisub(b);
2549
	db = analogsub_to_dahdisub(b);
2542

    
   
2550

   
2543
	tchan = p->subs[da].chan;
2551
	tchan = p->subs[da].chan;
2544
	p->subs[da].chan = p->subs[db].chan;
2552
	p->subs[da].chan = p->subs[db].chan;
2545
	p->subs[db].chan = tchan;
2553
	p->subs[db].chan = tchan;
2546

    
   
2554

   
2547
	tinthreeway = p->subs[da].inthreeway;
2555
	tinthreeway = p->subs[da].inthreeway;
2548
	p->subs[da].inthreeway = p->subs[db].inthreeway;
2556
	p->subs[da].inthreeway = p->subs[db].inthreeway;
2549
	p->subs[db].inthreeway = tinthreeway;
2557
	p->subs[db].inthreeway = tinthreeway;
2550

    
   
2558

   
2551
	p->subs[da].owner = ast_a;
2559
	p->subs[da].owner = ast_a;
2552
	p->subs[db].owner = ast_b;
2560
	p->subs[db].owner = ast_b;
2553

    
   
2561

   
2554
	if (ast_a)
2562
	if (ast_a)
2555
		ast_channel_set_fd(ast_a, 0, p->subs[da].dfd);
2563
		ast_channel_set_fd(ast_a, 0, p->subs[da].dfd);
2556
	if (ast_b)
2564
	if (ast_b)
2557
		ast_channel_set_fd(ast_b, 0, p->subs[db].dfd);
2565
		ast_channel_set_fd(ast_b, 0, p->subs[db].dfd);
2558

    
   
2566

   
2559
	wakeup_sub(p, a);
2567
	wakeup_sub(p, a);
2560
	wakeup_sub(p, b);
2568
	wakeup_sub(p, b);
2561

    
   
2569

   
2562
	return;
2570
	return;
2563
}
2571
}
2564

    
   
2572

   
2565
static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpbx, int idx, int law, const char *linkedid);
2573
static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpbx, int idx, int law, const char *linkedid);
2566

    
   
2574

   
2567
static struct ast_channel *my_new_analog_ast_channel(void *pvt, int state, int startpbx, enum analog_sub sub, const struct ast_channel *requestor)
2575
static struct ast_channel *my_new_analog_ast_channel(void *pvt, int state, int startpbx, enum analog_sub sub, const struct ast_channel *requestor)
2568
{
2576
{
2569
	struct dahdi_pvt *p = pvt;
2577
	struct dahdi_pvt *p = pvt;
2570
	int dsub = analogsub_to_dahdisub(sub);
2578
	int dsub = analogsub_to_dahdisub(sub);
2571

    
   
2579

   
2572
	return dahdi_new(p, state, startpbx, dsub, 0, requestor ? ast_channel_linkedid(requestor) : "");
2580
	return dahdi_new(p, state, startpbx, dsub, 0, requestor ? ast_channel_linkedid(requestor) : "");
2573
}
2581
}
2574

    
   
2582

   
2575
#if defined(HAVE_PRI) || defined(HAVE_SS7)
2583
#if defined(HAVE_PRI) || defined(HAVE_SS7)
2576
static int dahdi_setlaw(int dfd, int law)
2584
static int dahdi_setlaw(int dfd, int law)
2577
{
2585
{
2578
	int res;
2586
	int res;
2579
	res = ioctl(dfd, DAHDI_SETLAW, &law);
2587
	res = ioctl(dfd, DAHDI_SETLAW, &law);
2580
	if (res)
2588
	if (res)
2581
		return res;
2589
		return res;
2582
	return 0;
2590
	return 0;
2583
}
2591
}
2584
#endif	/* defined(HAVE_PRI) || defined(HAVE_SS7) */
2592
#endif	/* defined(HAVE_PRI) || defined(HAVE_SS7) */
2585

    
   
2593

   
2586
#if defined(HAVE_PRI)
2594
#if defined(HAVE_PRI)
2587
static struct ast_channel *my_new_pri_ast_channel(void *pvt, int state, enum sig_pri_law law, char *exten, const struct ast_channel *requestor)
2595
static struct ast_channel *my_new_pri_ast_channel(void *pvt, int state, enum sig_pri_law law, char *exten, const struct ast_channel *requestor)
2588
{
2596
{
2589
	struct dahdi_pvt *p = pvt;
2597
	struct dahdi_pvt *p = pvt;
2590
	int audio;
2598
	int audio;
2591
	int newlaw = -1;
2599
	int newlaw = -1;
2592

    
   
2600

   
2593
	switch (p->sig) {
2601
	switch (p->sig) {
2594
	case SIG_PRI_LIB_HANDLE_CASES:
2602
	case SIG_PRI_LIB_HANDLE_CASES:
2595
		if (((struct sig_pri_chan *) p->sig_pvt)->no_b_channel) {
2603
		if (((struct sig_pri_chan *) p->sig_pvt)->no_b_channel) {
2596
			/* PRI nobch pseudo channel.  Does not handle ioctl(DAHDI_AUDIOMODE) */
2604
			/* PRI nobch pseudo channel.  Does not handle ioctl(DAHDI_AUDIOMODE) */
2597
			break;
2605
			break;
2598
		}
2606
		}
2599
		/* Fall through */
2607
		/* Fall through */
2600
	default:
2608
	default:
2601
		/* Set to audio mode at this point */
2609
		/* Set to audio mode at this point */
2602
		audio = 1;
2610
		audio = 1;
2603
		if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &audio) == -1) {
2611
		if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &audio) == -1) {
2604
			ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d: %s\n",
2612
			ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d: %s\n",
2605
				p->channel, audio, strerror(errno));
2613
				p->channel, audio, strerror(errno));
2606
		}
2614
		}
2607
		break;
2615
		break;
2608
	}
2616
	}
2609

    
   
2617

   
2610
	if (law != SIG_PRI_DEFLAW) {
2618
	if (law != SIG_PRI_DEFLAW) {
2611
		dahdi_setlaw(p->subs[SUB_REAL].dfd, (law == SIG_PRI_ULAW) ? DAHDI_LAW_MULAW : DAHDI_LAW_ALAW);
2619
		dahdi_setlaw(p->subs[SUB_REAL].dfd, (law == SIG_PRI_ULAW) ? DAHDI_LAW_MULAW : DAHDI_LAW_ALAW);
2612
	}
2620
	}
2613

    
   
2621

   
2614
	ast_copy_string(p->exten, exten, sizeof(p->exten));
2622
	ast_copy_string(p->exten, exten, sizeof(p->exten));
2615

    
   
2623

   
2616
	switch (law) {
2624
	switch (law) {
2617
		case SIG_PRI_DEFLAW:
2625
		case SIG_PRI_DEFLAW:
2618
			newlaw = 0;
2626
			newlaw = 0;
2619
			break;
2627
			break;
2620
		case SIG_PRI_ALAW:
2628
		case SIG_PRI_ALAW:
2621
			newlaw = DAHDI_LAW_ALAW;
2629
			newlaw = DAHDI_LAW_ALAW;
2622
			break;
2630
			break;
2623
		case SIG_PRI_ULAW:
2631
		case SIG_PRI_ULAW:
2624
			newlaw = DAHDI_LAW_MULAW;
2632
			newlaw = DAHDI_LAW_MULAW;
2625
			break;
2633
			break;
2626
	}
2634
	}
2627
	return dahdi_new(p, state, 0, SUB_REAL, newlaw, requestor ? ast_channel_linkedid(requestor) : "");
2635
	return dahdi_new(p, state, 0, SUB_REAL, newlaw, requestor ? ast_channel_linkedid(requestor) : "");
2628
}
2636
}
2629
#endif	/* defined(HAVE_PRI) */
2637
#endif	/* defined(HAVE_PRI) */
2630

    
   
2638

   
2631
static int set_actual_gain(int fd, float rxgain, float txgain, float rxdrc, float txdrc, int law);
2639
static int set_actual_gain(int fd, float rxgain, float txgain, float rxdrc, float txdrc, int law);
2632

    
   
2640

   
2633
#if defined(HAVE_PRI)
2641
#if defined(HAVE_PRI)
2634
/*!
2642
/*!
2635
 * \internal
2643
 * \internal
2636
 * \brief Open the PRI channel media path.
2644
 * \brief Open the PRI channel media path.
2637
 * \since 1.8
2645
 * \since 1.8
2638
 *
2646
 *
2639
 * \param p Channel private control structure.
2647
 * \param p Channel private control structure.
2640
 *
2648
 *
2641
 * \return Nothing
2649
 * \return Nothing
2642
 */
2650
 */
2643
static void my_pri_open_media(void *p)
2651
static void my_pri_open_media(void *p)
2644
{
2652
{
2645
	struct dahdi_pvt *pvt = p;
2653
	struct dahdi_pvt *pvt = p;
2646
	int res;
2654
	int res;
2647
	int dfd;
2655
	int dfd;
2648
	int set_val;
2656
	int set_val;
2649

    
   
2657

   
2650
	dfd = pvt->subs[SUB_REAL].dfd;
2658
	dfd = pvt->subs[SUB_REAL].dfd;
2651

    
   
2659

   
2652
	/* Open the media path. */
2660
	/* Open the media path. */
2653
	set_val = 1;
2661
	set_val = 1;
2654
	res = ioctl(dfd, DAHDI_AUDIOMODE, &set_val);
2662
	res = ioctl(dfd, DAHDI_AUDIOMODE, &set_val);
2655
	if (res < 0) {
2663
	if (res < 0) {
2656
		ast_log(LOG_WARNING, "Unable to enable audio mode on channel %d (%s)\n",
2664
		ast_log(LOG_WARNING, "Unable to enable audio mode on channel %d (%s)\n",
2657
			pvt->channel, strerror(errno));
2665
			pvt->channel, strerror(errno));
2658
	}
2666
	}
2659

    
   
2667

   
2660
	/* Set correct companding law for this call. */
2668
	/* Set correct companding law for this call. */
2661
	res = dahdi_setlaw(dfd, pvt->law);
2669
	res = dahdi_setlaw(dfd, pvt->law);
2662
	if (res < 0) {
2670
	if (res < 0) {
2663
		ast_log(LOG_WARNING, "Unable to set law on channel %d\n", pvt->channel);
2671
		ast_log(LOG_WARNING, "Unable to set law on channel %d\n", pvt->channel);
2664
	}
2672
	}
2665

    
   
2673

   
2666
	/* Set correct gain for this call. */
2674
	/* Set correct gain for this call. */
2667
	if (pvt->digital) {
2675
	if (pvt->digital) {
2668
		res = set_actual_gain(dfd, 0, 0, pvt->rxdrc, pvt->txdrc, pvt->law);
2676
		res = set_actual_gain(dfd, 0, 0, pvt->rxdrc, pvt->txdrc, pvt->law);
2669
	} else {
2677
	} else {
2670
		res = set_actual_gain(dfd, pvt->rxgain, pvt->txgain, pvt->rxdrc, pvt->txdrc,
2678
		res = set_actual_gain(dfd, pvt->rxgain, pvt->txgain, pvt->rxdrc, pvt->txdrc,
2671
			pvt->law);
2679
			pvt->law);
2672
	}
2680
	}
2673
	if (res < 0) {
2681
	if (res < 0) {
2674
		ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", pvt->channel);
2682
		ast_log(LOG_WARNING, "Unable to set gains on channel %d\n", pvt->channel);
2675
	}
2683
	}
2676

    
   
2684

   
2677
	if (pvt->dsp_features && pvt->dsp) {
2685
	if (pvt->dsp_features && pvt->dsp) {
2678
		ast_dsp_set_features(pvt->dsp, pvt->dsp_features);
2686
		ast_dsp_set_features(pvt->dsp, pvt->dsp_features);
2679
		pvt->dsp_features = 0;
2687
		pvt->dsp_features = 0;
2680
	}
2688
	}
2681
}
2689
}
2682
#endif	/* defined(HAVE_PRI) */
2690
#endif	/* defined(HAVE_PRI) */
2683

    
   
2691

   
2684
static int unalloc_sub(struct dahdi_pvt *p, int x);
2692
static int unalloc_sub(struct dahdi_pvt *p, int x);
2685

    
   
2693

   
2686
static int my_unallocate_sub(void *pvt, enum analog_sub analogsub)
2694
static int my_unallocate_sub(void *pvt, enum analog_sub analogsub)
2687
{
2695
{
2688
	struct dahdi_pvt *p = pvt;
2696
	struct dahdi_pvt *p = pvt;
2689

    
   
2697

   
2690
	return unalloc_sub(p, analogsub_to_dahdisub(analogsub));
2698
	return unalloc_sub(p, analogsub_to_dahdisub(analogsub));
2691
}
2699
}
2692

    
   
2700

   
2693
static int alloc_sub(struct dahdi_pvt *p, int x);
2701
static int alloc_sub(struct dahdi_pvt *p, int x);
2694

    
   
2702

   
2695
static int my_allocate_sub(void *pvt, enum analog_sub analogsub)
2703
static int my_allocate_sub(void *pvt, enum analog_sub analogsub)
2696
{
2704
{
2697
	struct dahdi_pvt *p = pvt;
2705
	struct dahdi_pvt *p = pvt;
2698

    
   
2706

   
2699
	return alloc_sub(p, analogsub_to_dahdisub(analogsub));
2707
	return alloc_sub(p, analogsub_to_dahdisub(analogsub));
2700
}
2708
}
2701

    
   
2709

   
2702
static int has_voicemail(struct dahdi_pvt *p);
2710
static int has_voicemail(struct dahdi_pvt *p);
2703

    
   
2711

   
2704
static int my_has_voicemail(void *pvt)
2712
static int my_has_voicemail(void *pvt)
2705
{
2713
{
2706
	struct dahdi_pvt *p = pvt;
2714
	struct dahdi_pvt *p = pvt;
2707

    
   
2715

   
2708
	return has_voicemail(p);
2716
	return has_voicemail(p);
2709
}
2717
}
2710

    
   
2718

   
2711
static int my_play_tone(void *pvt, enum analog_sub sub, enum analog_tone tone)
2719
static int my_play_tone(void *pvt, enum analog_sub sub, enum analog_tone tone)
2712
{
2720
{
2713
	struct dahdi_pvt *p = pvt;
2721
	struct dahdi_pvt *p = pvt;
2714
	int index;
2722
	int index;
2715

    
   
2723

   
2716
	index = analogsub_to_dahdisub(sub);
2724
	index = analogsub_to_dahdisub(sub);
2717

    
   
2725

   
2718
	return tone_zone_play_tone(p->subs[index].dfd, analog_tone_to_dahditone(tone));
2726
	return tone_zone_play_tone(p->subs[index].dfd, analog_tone_to_dahditone(tone));
2719
}
2727
}
2720

    
   
2728

   
2721
static enum analog_event dahdievent_to_analogevent(int event)
2729
static enum analog_event dahdievent_to_analogevent(int event)
2722
{
2730
{
2723
	enum analog_event res;
2731
	enum analog_event res;
2724

    
   
2732

   
2725
	switch (event) {
2733
	switch (event) {
2726
	case DAHDI_EVENT_ONHOOK:
2734
	case DAHDI_EVENT_ONHOOK:
2727
		res = ANALOG_EVENT_ONHOOK;
2735
		res = ANALOG_EVENT_ONHOOK;
2728
		break;
2736
		break;
2729
	case DAHDI_EVENT_RINGOFFHOOK:
2737
	case DAHDI_EVENT_RINGOFFHOOK:
2730
		res = ANALOG_EVENT_RINGOFFHOOK;
2738
		res = ANALOG_EVENT_RINGOFFHOOK;
2731
		break;
2739
		break;
2732
	case DAHDI_EVENT_WINKFLASH:
2740
	case DAHDI_EVENT_WINKFLASH:
2733
		res = ANALOG_EVENT_WINKFLASH;
2741
		res = ANALOG_EVENT_WINKFLASH;
2734
		break;
2742
		break;
2735
	case DAHDI_EVENT_ALARM:
2743
	case DAHDI_EVENT_ALARM:
2736
		res = ANALOG_EVENT_ALARM;
2744
		res = ANALOG_EVENT_ALARM;
2737
		break;
2745
		break;
2738
	case DAHDI_EVENT_NOALARM:
2746
	case DAHDI_EVENT_NOALARM:
2739
		res = ANALOG_EVENT_NOALARM;
2747
		res = ANALOG_EVENT_NOALARM;
2740
		break;
2748
		break;
2741
	case DAHDI_EVENT_DIALCOMPLETE:
2749
	case DAHDI_EVENT_DIALCOMPLETE:
2742
		res = ANALOG_EVENT_DIALCOMPLETE;
2750
		res = ANALOG_EVENT_DIALCOMPLETE;
2743
		break;
2751
		break;
2744
	case DAHDI_EVENT_RINGERON:
2752
	case DAHDI_EVENT_RINGERON:
2745
		res = ANALOG_EVENT_RINGERON;
2753
		res = ANALOG_EVENT_RINGERON;
2746
		break;
2754
		break;
2747
	case DAHDI_EVENT_RINGEROFF:
2755
	case DAHDI_EVENT_RINGEROFF:
2748
		res = ANALOG_EVENT_RINGEROFF;
2756
		res = ANALOG_EVENT_RINGEROFF;
2749
		break;
2757
		break;
2750
	case DAHDI_EVENT_HOOKCOMPLETE:
2758
	case DAHDI_EVENT_HOOKCOMPLETE:
2751
		res = ANALOG_EVENT_HOOKCOMPLETE;
2759
		res = ANALOG_EVENT_HOOKCOMPLETE;
2752
		break;
2760
		break;
2753
	case DAHDI_EVENT_PULSE_START:
2761
	case DAHDI_EVENT_PULSE_START:
2754
		res = ANALOG_EVENT_PULSE_START;
2762
		res = ANALOG_EVENT_PULSE_START;
2755
		break;
2763
		break;
2756
	case DAHDI_EVENT_POLARITY:
2764
	case DAHDI_EVENT_POLARITY:
2757
		res = ANALOG_EVENT_POLARITY;
2765
		res = ANALOG_EVENT_POLARITY;
2758
		break;
2766
		break;
2759
	case DAHDI_EVENT_RINGBEGIN:
2767
	case DAHDI_EVENT_RINGBEGIN:
2760
		res = ANALOG_EVENT_RINGBEGIN;
2768
		res = ANALOG_EVENT_RINGBEGIN;
2761
		break;
2769
		break;
2762
	case DAHDI_EVENT_EC_DISABLED:
2770
	case DAHDI_EVENT_EC_DISABLED:
2763
		res = ANALOG_EVENT_EC_DISABLED;
2771
		res = ANALOG_EVENT_EC_DISABLED;
2764
		break;
2772
		break;
2765
	case DAHDI_EVENT_REMOVED:
2773
	case DAHDI_EVENT_REMOVED:
2766
		res = ANALOG_EVENT_REMOVED;
2774
		res = ANALOG_EVENT_REMOVED;
2767
		break;
2775
		break;
2768
	case DAHDI_EVENT_NEONMWI_ACTIVE:
2776
	case DAHDI_EVENT_NEONMWI_ACTIVE:
2769
		res = ANALOG_EVENT_NEONMWI_ACTIVE;
2777
		res = ANALOG_EVENT_NEONMWI_ACTIVE;
2770
		break;
2778
		break;
2771
	case DAHDI_EVENT_NEONMWI_INACTIVE:
2779
	case DAHDI_EVENT_NEONMWI_INACTIVE:
2772
		res = ANALOG_EVENT_NEONMWI_INACTIVE;
2780
		res = ANALOG_EVENT_NEONMWI_INACTIVE;
2773
		break;
2781
		break;
2774
#ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE
2782
#ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE
2775
	case DAHDI_EVENT_TX_CED_DETECTED:
2783
	case DAHDI_EVENT_TX_CED_DETECTED:
2776
		res = ANALOG_EVENT_TX_CED_DETECTED;
2784
		res = ANALOG_EVENT_TX_CED_DETECTED;
2777
		break;
2785
		break;
2778
	case DAHDI_EVENT_RX_CED_DETECTED:
2786
	case DAHDI_EVENT_RX_CED_DETECTED:
2779
		res = ANALOG_EVENT_RX_CED_DETECTED;
2787
		res = ANALOG_EVENT_RX_CED_DETECTED;
2780
		break;
2788
		break;
2781
	case DAHDI_EVENT_EC_NLP_DISABLED:
2789
	case DAHDI_EVENT_EC_NLP_DISABLED:
2782
		res = ANALOG_EVENT_EC_NLP_DISABLED;
2790
		res = ANALOG_EVENT_EC_NLP_DISABLED;
2783
		break;
2791
		break;
2784
	case DAHDI_EVENT_EC_NLP_ENABLED:
2792
	case DAHDI_EVENT_EC_NLP_ENABLED:
2785
		res = ANALOG_EVENT_EC_NLP_ENABLED;
2793
		res = ANALOG_EVENT_EC_NLP_ENABLED;
2786
		break;
2794
		break;
2787
#endif
2795
#endif
2788
	case DAHDI_EVENT_PULSEDIGIT:
2796
	case DAHDI_EVENT_PULSEDIGIT:
2789
		res = ANALOG_EVENT_PULSEDIGIT;
2797
		res = ANALOG_EVENT_PULSEDIGIT;
2790
		break;
2798
		break;
2791
	case DAHDI_EVENT_DTMFDOWN:
2799
	case DAHDI_EVENT_DTMFDOWN:
2792
		res = ANALOG_EVENT_DTMFDOWN;
2800
		res = ANALOG_EVENT_DTMFDOWN;
2793
		break;
2801
		break;
2794
	case DAHDI_EVENT_DTMFUP:
2802
	case DAHDI_EVENT_DTMFUP:
2795
		res = ANALOG_EVENT_DTMFUP;
2803
		res = ANALOG_EVENT_DTMFUP;
2796
		break;
2804
		break;
2797
	default:
2805
	default:
2798
		switch(event & 0xFFFF0000) {
2806
		switch(event & 0xFFFF0000) {
2799
		case DAHDI_EVENT_PULSEDIGIT:
2807
		case DAHDI_EVENT_PULSEDIGIT:
2800
		case DAHDI_EVENT_DTMFDOWN:
2808
		case DAHDI_EVENT_DTMFDOWN:
2801
		case DAHDI_EVENT_DTMFUP:
2809
		case DAHDI_EVENT_DTMFUP:
2802
			/* The event includes a digit number in the low word.
2810
			/* The event includes a digit number in the low word.
2803
			 * Converting it to a 'enum analog_event' would remove
2811
			 * Converting it to a 'enum analog_event' would remove
2804
			 * that information. Thus it is returned as-is.
2812
			 * that information. Thus it is returned as-is.
2805
			 */
2813
			 */
2806
			return event;
2814
			return event;
2807
		}
2815
		}
2808

    
   
2816

   
2809
		res = ANALOG_EVENT_ERROR;
2817
		res = ANALOG_EVENT_ERROR;
2810
		break;
2818
		break;
2811
	}
2819
	}
2812

    
   
2820

   
2813
	return res;
2821
	return res;
2814
}
2822
}
2815

    
   
2823

   
2816
static inline int dahdi_wait_event(int fd);
2824
static inline int dahdi_wait_event(int fd);
2817

    
   
2825

   
2818
static int my_wait_event(void *pvt)
2826
static int my_wait_event(void *pvt)
2819
{
2827
{
2820
	struct dahdi_pvt *p = pvt;
2828
	struct dahdi_pvt *p = pvt;
2821

    
   
2829

   
2822
	return dahdi_wait_event(p->subs[SUB_REAL].dfd);
2830
	return dahdi_wait_event(p->subs[SUB_REAL].dfd);
2823
}
2831
}
2824

    
   
2832

   
2825
static int my_get_event(void *pvt)
2833
static int my_get_event(void *pvt)
2826
{
2834
{
2827
	struct dahdi_pvt *p = pvt;
2835
	struct dahdi_pvt *p = pvt;
2828
	int res;
2836
	int res;
2829

    
   
2837

   
2830
	if (p->fake_event) {
2838
	if (p->fake_event) {
2831
		res = p->fake_event;
2839
		res = p->fake_event;
2832
		p->fake_event = 0;
2840
		p->fake_event = 0;
2833
	} else
2841
	} else
2834
		res = dahdi_get_event(p->subs[SUB_REAL].dfd);
2842
		res = dahdi_get_event(p->subs[SUB_REAL].dfd);
2835

    
   
2843

   
2836
	return dahdievent_to_analogevent(res);
2844
	return dahdievent_to_analogevent(res);
2837
}
2845
}
2838

    
   
2846

   
2839
static int my_is_off_hook(void *pvt)
2847
static int my_is_off_hook(void *pvt)
2840
{
2848
{
2841
	struct dahdi_pvt *p = pvt;
2849
	struct dahdi_pvt *p = pvt;
2842
	int res;
2850
	int res;
2843
	struct dahdi_params par;
2851
	struct dahdi_params par;
2844

    
   
2852

   
2845
	memset(&par, 0, sizeof(par));
2853
	memset(&par, 0, sizeof(par));
2846

    
   
2854

   
2847
	if (p->subs[SUB_REAL].dfd > -1)
2855
	if (p->subs[SUB_REAL].dfd > -1)
2848
		res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &par);
2856
		res = ioctl(p->subs[SUB_REAL].dfd, DAHDI_GET_PARAMS, &par);
2849
	else {
2857
	else {
2850
		/* Assume not off hook on CVRS */
2858
		/* Assume not off hook on CVRS */
2851
		res = 0;
2859
		res = 0;
2852
		par.rxisoffhook = 0;
2860
		par.rxisoffhook = 0;
2853
	}
2861
	}
2854
	if (res) {
2862
	if (res) {
2855
		ast_log(LOG_WARNING, "Unable to check hook state on channel %d: %s\n", p->channel, strerror(errno));
2863
		ast_log(LOG_WARNING, "Unable to check hook state on channel %d: %s\n", p->channel, strerror(errno));
2856
	}
2864
	}
2857

    
   
2865

   
2858
	if ((p->sig == SIG_FXSKS) || (p->sig == SIG_FXSGS)) {
2866
	if ((p->sig == SIG_FXSKS) || (p->sig == SIG_FXSGS)) {
2859
		/* When "onhook" that means no battery on the line, and thus
2867
		/* When "onhook" that means no battery on the line, and thus
2860
		it is out of service..., if it's on a TDM card... If it's a channel
2868
		it is out of service..., if it's on a TDM card... If it's a channel
2861
		bank, there is no telling... */
2869
		bank, there is no telling... */
2862
		return (par.rxbits > -1) || par.rxisoffhook;
2870
		return (par.rxbits > -1) || par.rxisoffhook;
2863
	}
2871
	}
2864

    
   
2872

   
2865
	return par.rxisoffhook;
2873
	return par.rxisoffhook;
2866
}
2874
}
2867

    
   
2875

   
2868
static void dahdi_enable_ec(struct dahdi_pvt *p);
2876
static void dahdi_enable_ec(struct dahdi_pvt *p);
2869
static void dahdi_disable_ec(struct dahdi_pvt *p);
2877
static void dahdi_disable_ec(struct dahdi_pvt *p);
2870

    
   
2878

   
2871
static int my_set_echocanceller(void *pvt, int enable)
2879
static int my_set_echocanceller(void *pvt, int enable)
2872
{
2880
{
2873
	struct dahdi_pvt *p = pvt;
2881
	struct dahdi_pvt *p = pvt;
2874

    
   
2882

   
2875
	if (enable)
2883
	if (enable)
2876
		dahdi_enable_ec(p);
2884
		dahdi_enable_ec(p);
2877
	else
2885
	else
2878
		dahdi_disable_ec(p);
2886
		dahdi_disable_ec(p);
2879

    
   
2887

   
2880
	return 0;
2888
	return 0;
2881
}
2889
}
2882

    
   
2890

   
2883
static int dahdi_ring_phone(struct dahdi_pvt *p);
2891
static int dahdi_ring_phone(struct dahdi_pvt *p);
2884

    
   
2892

   
2885
static int my_ring(void *pvt)
2893
static int my_ring(void *pvt)
2886
{
2894
{
2887
	struct dahdi_pvt *p = pvt;
2895
	struct dahdi_pvt *p = pvt;
2888

    
   
2896

   
2889
	return dahdi_ring_phone(p);
2897
	return dahdi_ring_phone(p);
2890
}
2898
}
2891

    
   
2899

   
2892
static int my_flash(void *pvt)
2900
static int my_flash(void *pvt)
2893
{
2901
{
2894
	struct dahdi_pvt *p = pvt;
2902
	struct dahdi_pvt *p = pvt;
2895
	int func = DAHDI_FLASH;
2903
	int func = DAHDI_FLASH;
2896
	return ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &func);
2904
	return ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &func);
2897
}
2905
}
2898

    
   
2906

   
2899
static inline int dahdi_set_hook(int fd, int hs);
2907
static inline int dahdi_set_hook(int fd, int hs);
2900

    
   
2908

   
2901
static int my_off_hook(void *pvt)
2909
static int my_off_hook(void *pvt)
2902
{
2910
{
2903
	struct dahdi_pvt *p = pvt;
2911
	struct dahdi_pvt *p = pvt;
2904
	return dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
2912
	return dahdi_set_hook(p->subs[SUB_REAL].dfd, DAHDI_OFFHOOK);
2905
}
2913
}
2906

    
   
2914

   
2907
static void my_set_needringing(void *pvt, int value)
2915
static void my_set_needringing(void *pvt, int value)
2908
{
2916
{
2909
	struct dahdi_pvt *p = pvt;
2917
	struct dahdi_pvt *p = pvt;
2910
	p->subs[SUB_REAL].needringing = value;
2918
	p->subs[SUB_REAL].needringing = value;
2911
}
2919
}
2912

    
   
2920

   
2913
static void my_set_polarity(void *pvt, int value)
2921
static void my_set_polarity(void *pvt, int value)
2914
{
2922
{
2915
	struct dahdi_pvt *p = pvt;
2923
	struct dahdi_pvt *p = pvt;
2916

    
   
2924

   
2917
	if (p->channel == CHAN_PSEUDO) {
2925
	if (p->channel == CHAN_PSEUDO) {
2918
		return;
2926
		return;
2919
	}
2927
	}
2920
	p->polarity = value;
2928
	p->polarity = value;
2921
	ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETPOLARITY, &value);
2929
	ioctl(p->subs[SUB_REAL].dfd, DAHDI_SETPOLARITY, &value);
2922
}
2930
}
2923

    
   
2931

   
2924
static void my_start_polarityswitch(void *pvt)
2932
static void my_start_polarityswitch(void *pvt)
2925
{
2933
{
2926
	struct dahdi_pvt *p = pvt;
2934
	struct dahdi_pvt *p = pvt;
2927

    
   
2935

   
2928
	if (p->answeronpolarityswitch || p->hanguponpolarityswitch) {
2936
	if (p->answeronpolarityswitch || p->hanguponpolarityswitch) {
2929
		my_set_polarity(pvt, 0);
2937
		my_set_polarity(pvt, 0);
2930
	}
2938
	}
2931
}
2939
}
2932

    
   
2940

   
2933
static void my_answer_polarityswitch(void *pvt)
2941
static void my_answer_polarityswitch(void *pvt)
2934
{
2942
{
2935
	struct dahdi_pvt *p = pvt;
2943
	struct dahdi_pvt *p = pvt;
2936

    
   
2944

   
2937
	if (!p->answeronpolarityswitch) {
2945
	if (!p->answeronpolarityswitch) {
2938
		return;
2946
		return;
2939
	}
2947
	}
2940

    
   
2948

   
2941
	my_set_polarity(pvt, 1);
2949
	my_set_polarity(pvt, 1);
2942
}
2950
}
2943

    
   
2951

   
2944
static void my_hangup_polarityswitch(void *pvt)
2952
static void my_hangup_polarityswitch(void *pvt)
2945
{
2953
{
2946
	struct dahdi_pvt *p = pvt;
2954
	struct dahdi_pvt *p = pvt;
2947

    
   
2955

   
2948
	if (!p->hanguponpolarityswitch) {
2956
	if (!p->hanguponpolarityswitch) {
2949
		return;
2957
		return;
2950
	}
2958
	}
2951

    
   
2959

   
2952
	if (p->answeronpolarityswitch) {
2960
	if (p->answeronpolarityswitch) {
2953
		my_set_polarity(pvt, 0);
2961
		my_set_polarity(pvt, 0);
2954
	} else {
2962
	} else {
2955
		my_set_polarity(pvt, 1);
2963
		my_set_polarity(pvt, 1);
2956
	}
2964
	}
2957
}
2965
}
2958

    
   
2966

   
2959
static int my_start(void *pvt)
2967
static int my_start(void *pvt)
2960
{
2968
{
2961
	struct dahdi_pvt *p = pvt;
2969
	struct dahdi_pvt *p = pvt;
2962
	int x = DAHDI_START;
2970
	int x = DAHDI_START;
2963

    
   
2971

   
2964
	return ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
2972
	return ioctl(p->subs[SUB_REAL].dfd, DAHDI_HOOK, &x);
2965
}
2973
}
2966

    
   
2974

   
2967
static int my_dial_digits(void *pvt, enum analog_sub sub, struct analog_dialoperation *dop)
2975
static int my_dial_digits(void *pvt, enum analog_sub sub, struct analog_dialoperation *dop)
2968
{
2976
{
2969
	int index = analogsub_to_dahdisub(sub);
2977
	int index = analogsub_to_dahdisub(sub);
2970
	int res;
2978
	int res;
2971
	struct dahdi_pvt *p = pvt;
2979
	struct dahdi_pvt *p = pvt;
2972
	struct dahdi_dialoperation ddop;
2980
	struct dahdi_dialoperation ddop;
2973

    
   
2981

   
2974
	if (dop->op != ANALOG_DIAL_OP_REPLACE) {
2982
	if (dop->op != ANALOG_DIAL_OP_REPLACE) {
2975
		ast_log(LOG_ERROR, "Fix the dial_digits callback!\n");
2983
		ast_log(LOG_ERROR, "Fix the dial_digits callback!\n");
2976
		return -1;
2984
		return -1;
2977
	}
2985
	}
2978

    
   
2986

   
2979
	if (sub != ANALOG_SUB_REAL) {
2987
	if (sub != ANALOG_SUB_REAL) {
2980
		ast_log(LOG_ERROR, "Trying to dial_digits '%s' on channel %d subchannel %d\n",
2988
		ast_log(LOG_ERROR, "Trying to dial_digits '%s' on channel %d subchannel %d\n",
2981
			dop->dialstr, p->channel, sub);
2989
			dop->dialstr, p->channel, sub);
2982
		return -1;
2990
		return -1;
2983
	}
2991
	}
2984

    
   
2992

   
2985
	ddop.op = DAHDI_DIAL_OP_REPLACE;
2993
	ddop.op = DAHDI_DIAL_OP_REPLACE;
2986
	ast_copy_string(ddop.dialstr, dop->dialstr, sizeof(ddop.dialstr));
2994
	ast_copy_string(ddop.dialstr, dop->dialstr, sizeof(ddop.dialstr));
2987

    
   
2995

   
2988
	ast_debug(1, "Channel %d: Sending '%s' to DAHDI_DIAL.\n", p->channel, ddop.dialstr);
2996
	ast_debug(1, "Channel %d: Sending '%s' to DAHDI_DIAL.\n", p->channel, ddop.dialstr);
2989

    
   
2997

   
2990
	res = ioctl(p->subs[index].dfd, DAHDI_DIAL, &ddop);
2998
	res = ioctl(p->subs[index].dfd, DAHDI_DIAL, &ddop);
2991
	if (res == -1) {
2999
	if (res == -1) {
2992
		ast_debug(1, "DAHDI_DIAL ioctl failed on %s: %s\n", ast_channel_name(p->owner), strerror(errno));
3000
		ast_debug(1, "DAHDI_DIAL ioctl failed on %s: %s\n", ast_channel_name(p->owner), strerror(errno));
2993
	}
3001
	}
2994

    
   
3002

   
2995
	return res;
3003
	return res;
2996
}
3004
}
2997

    
   
3005

   
2998
static void dahdi_train_ec(struct dahdi_pvt *p);
3006
static void dahdi_train_ec(struct dahdi_pvt *p);
2999

    
   
3007

   
3000
static int my_train_echocanceller(void *pvt)
3008
static int my_train_echocanceller(void *pvt)
3001
{
3009
{
3002
	struct dahdi_pvt *p = pvt;
3010
	struct dahdi_pvt *p = pvt;
3003

    
   
3011

   
3004
	dahdi_train_ec(p);
3012
	dahdi_train_ec(p);
3005

    
   
3013

   
3006
	return 0;
3014
	return 0;
3007
}
3015
}
3008

    
   
3016

   
3009
static int my_is_dialing(void *pvt, enum analog_sub sub)
3017
static int my_is_dialing(void *pvt, enum analog_sub sub)
3010
{
3018
{
3011
	struct dahdi_pvt *p = pvt;
3019
	struct dahdi_pvt *p = pvt;
3012
	int index;
3020
	int index;
3013
	int x;
3021
	int x;
3014

    
   
3022

   
3015
	index = analogsub_to_dahdisub(sub);
3023
	index = analogsub_to_dahdisub(sub);
3016

    
   
3024

   
3017
	if (ioctl(p->subs[index].dfd, DAHDI_DIALING, &x)) {
3025
	if (ioctl(p->subs[index].dfd, DAHDI_DIALING, &x)) {
3018
		ast_debug(1, "DAHDI_DIALING ioctl failed!\n");
3026
		ast_debug(1, "DAHDI_DIALING ioctl failed!\n");
3019
		return -1;
3027
		return -1;
3020
	}
3028
	}
3021

    
   
3029

   
3022
	return x;
3030
	return x;
3023
}
3031
}
3024

    
   
3032

   
3025
static int my_on_hook(void *pvt)
3033
static int my_on_hook(void *pvt)
3026
{
3034
{
3027
	struct dahdi_pvt *p = pvt;
3035
	struct dahdi_pvt *p = pvt;
3028
	return dahdi_set_hook(p->subs[ANALOG_SUB_REAL].dfd, DAHDI_ONHOOK);
3036
	return dahdi_set_hook(p->subs[ANALOG_SUB_REAL].dfd, DAHDI_ONHOOK);
3029
}
3037
}
3030

    
   
3038

   
3031
#if defined(HAVE_PRI)
3039
#if defined(HAVE_PRI)
3032
static void my_pri_fixup_chans(void *chan_old, void *chan_new)
3040
static void my_pri_fixup_chans(void *chan_old, void *chan_new)
3033
{
3041
{
3034
	struct dahdi_pvt *old_chan = chan_old;
3042
	struct dahdi_pvt *old_chan = chan_old;
3035
	struct dahdi_pvt *new_chan = chan_new;
3043
	struct dahdi_pvt *new_chan = chan_new;
3036

    
   
3044

   
3037
	new_chan->owner = old_chan->owner;
3045
	new_chan->owner = old_chan->owner;
3038
	old_chan->owner = NULL;
3046
	old_chan->owner = NULL;
3039
	if (new_chan->owner) {
3047
	if (new_chan->owner) {
3040
		new_chan->owner->tech_pvt = new_chan;
3048
		new_chan->owner->tech_pvt = new_chan;
3041
		new_chan->owner->fds[0] = new_chan->subs[SUB_REAL].dfd;
3049
		new_chan->owner->fds[0] = new_chan->subs[SUB_REAL].dfd;
3042
		new_chan->subs[SUB_REAL].owner = old_chan->subs[SUB_REAL].owner;
3050
		new_chan->subs[SUB_REAL].owner = old_chan->subs[SUB_REAL].owner;
3043
		old_chan->subs[SUB_REAL].owner = NULL;
3051
		old_chan->subs[SUB_REAL].owner = NULL;
3044
	}
3052
	}
3045
	/* Copy any DSP that may be present */
3053
	/* Copy any DSP that may be present */
3046
	new_chan->dsp = old_chan->dsp;
3054
	new_chan->dsp = old_chan->dsp;
3047
	new_chan->dsp_features = old_chan->dsp_features;
3055
	new_chan->dsp_features = old_chan->dsp_features;
3048
	old_chan->dsp = NULL;
3056
	old_chan->dsp = NULL;
3049
	old_chan->dsp_features = 0;
3057
	old_chan->dsp_features = 0;
3050

    
   
3058

   
3051
	/* Transfer flags from the old channel. */
3059
	/* Transfer flags from the old channel. */
3052
	new_chan->dialing = old_chan->dialing;
3060
	new_chan->dialing = old_chan->dialing;
3053
	new_chan->digital = old_chan->digital;
3061
	new_chan->digital = old_chan->digital;
3054
	new_chan->outgoing = old_chan->outgoing;
3062
	new_chan->outgoing = old_chan->outgoing;
3055
	old_chan->dialing = 0;
3063
	old_chan->dialing = 0;
3056
	old_chan->digital = 0;
3064
	old_chan->digital = 0;
3057
	old_chan->outgoing = 0;
3065
	old_chan->outgoing = 0;
3058

    
   
3066

   
3059
	/* More stuff to transfer to the new channel. */
3067
	/* More stuff to transfer to the new channel. */
3060
	new_chan->law = old_chan->law;
3068
	new_chan->law = old_chan->law;
3061
	strcpy(new_chan->dialstring, old_chan->dialstring);
3069
	strcpy(new_chan->dialstring, old_chan->dialstring);
3062
}
3070
}
3063
#endif	/* defined(HAVE_PRI) */
3071
#endif	/* defined(HAVE_PRI) */
3064

    
   
3072

   
3065
#if defined(HAVE_PRI)
3073
#if defined(HAVE_PRI)
3066
static int sig_pri_tone_to_dahditone(enum sig_pri_tone tone)
3074
static int sig_pri_tone_to_dahditone(enum sig_pri_tone tone)
3067
{
3075
{
3068
	switch (tone) {
3076
	switch (tone) {
3069
	case SIG_PRI_TONE_RINGTONE:
3077
	case SIG_PRI_TONE_RINGTONE:
3070
		return DAHDI_TONE_RINGTONE;
3078
		return DAHDI_TONE_RINGTONE;
3071
	case SIG_PRI_TONE_STUTTER:
3079
	case SIG_PRI_TONE_STUTTER:
3072
		return DAHDI_TONE_STUTTER;
3080
		return DAHDI_TONE_STUTTER;
3073
	case SIG_PRI_TONE_CONGESTION:
3081
	case SIG_PRI_TONE_CONGESTION:
3074
		return DAHDI_TONE_CONGESTION;
3082
		return DAHDI_TONE_CONGESTION;
3075
	case SIG_PRI_TONE_DIALTONE:
3083
	case SIG_PRI_TONE_DIALTONE:
3076
		return DAHDI_TONE_DIALTONE;
3084
		return DAHDI_TONE_DIALTONE;
3077
	case SIG_PRI_TONE_DIALRECALL:
3085
	case SIG_PRI_TONE_DIALRECALL:
3078
		return DAHDI_TONE_DIALRECALL;
3086
		return DAHDI_TONE_DIALRECALL;
3079
	case SIG_PRI_TONE_INFO:
3087
	case SIG_PRI_TONE_INFO:
3080
		return DAHDI_TONE_INFO;
3088
		return DAHDI_TONE_INFO;
3081
	case SIG_PRI_TONE_BUSY:
3089
	case SIG_PRI_TONE_BUSY:
3082
		return DAHDI_TONE_BUSY;
3090
		return DAHDI_TONE_BUSY;
3083
	default:
3091
	default:
3084
		return -1;
3092
		return -1;
3085
	}
3093
	}
3086
}
3094
}
3087
#endif	/* defined(HAVE_PRI) */
3095
#endif	/* defined(HAVE_PRI) */
3088

    
   
3096

   
3089
#if defined(HAVE_PRI)
3097
#if defined(HAVE_PRI)
3090
static void my_handle_dchan_exception(struct sig_pri_span *pri, int index)
3098
static void my_handle_dchan_exception(struct sig_pri_span *pri, int index)
3091
{
3099
{
3092
	int x;
3100
	int x;
3093

    
   
3101

   
3094
	ioctl(pri->fds[index], DAHDI_GETEVENT, &x);
3102
	ioctl(pri->fds[index], DAHDI_GETEVENT, &x);
3095
	if (x) {
3103
	if (x) {
3096
		ast_log(LOG_NOTICE, "PRI got event: %s (%d) on D-channel of span %d\n", event2str(x), x, pri->span);
3104
		ast_log(LOG_NOTICE, "PRI got event: %s (%d) on D-channel of span %d\n", event2str(x), x, pri->span);
3097
	}
3105
	}
3098
	/* Keep track of alarm state */
3106
	/* Keep track of alarm state */
3099
	switch (x) {
3107
	switch (x) {
3100
	case DAHDI_EVENT_ALARM:
3108
	case DAHDI_EVENT_ALARM:
3101
		pri_event_alarm(pri, index, 0);
3109
		pri_event_alarm(pri, index, 0);
3102
		break;
3110
		break;
3103
	case DAHDI_EVENT_NOALARM:
3111
	case DAHDI_EVENT_NOALARM:
3104
		pri_event_noalarm(pri, index, 0);
3112
		pri_event_noalarm(pri, index, 0);
3105
		break;
3113
		break;
3106
	default:
3114
	default:
3107
		break;
3115
		break;
3108
	}
3116
	}
3109
}
3117
}
3110
#endif	/* defined(HAVE_PRI) */
3118
#endif	/* defined(HAVE_PRI) */
3111

    
   
3119

   
3112
#if defined(HAVE_PRI)
3120
#if defined(HAVE_PRI)
3113
static int my_pri_play_tone(void *pvt, enum sig_pri_tone tone)
3121
static int my_pri_play_tone(void *pvt, enum sig_pri_tone tone)
3114
{
3122
{
3115
	struct dahdi_pvt *p = pvt;
3123
	struct dahdi_pvt *p = pvt;
3116

    
   
3124

   
3117
	return tone_zone_play_tone(p->subs[SUB_REAL].dfd, sig_pri_tone_to_dahditone(tone));
3125
	return tone_zone_play_tone(p->subs[SUB_REAL].dfd, sig_pri_tone_to_dahditone(tone));
3118
}
3126
}
3119
#endif	/* defined(HAVE_PRI) */
3127
#endif	/* defined(HAVE_PRI) */
3120

    
   
3128

   
3121
#if defined(HAVE_PRI) || defined(HAVE_SS7)
3129
#if defined(HAVE_PRI) || defined(HAVE_SS7)
3122
/*!
3130
/*!
3123
 * \internal
3131
 * \internal
3124
 * \brief Set the caller id information.
3132
 * \brief Set the caller id information.
3125
 * \since 1.8
3133
 * \since 1.8
3126
 *
3134
 *
3127
 * \param pvt DAHDI private structure
3135
 * \param pvt DAHDI private structure
3128
 * \param caller Caller-id information to set.
3136
 * \param caller Caller-id information to set.
3129
 *
3137
 *
3130
 * \return Nothing
3138
 * \return Nothing
3131
 */
3139
 */
3132
static void my_set_callerid(void *pvt, const struct ast_party_caller *caller)
3140
static void my_set_callerid(void *pvt, const struct ast_party_caller *caller)
3133
{
3141
{
3134
	struct dahdi_pvt *p = pvt;
3142
	struct dahdi_pvt *p = pvt;
3135

    
   
3143

   
3136
	ast_copy_string(p->cid_num,
3144
	ast_copy_string(p->cid_num,
3137
		S_COR(caller->id.number.valid, caller->id.number.str, ""),
3145
		S_COR(caller->id.number.valid, caller->id.number.str, ""),
3138
		sizeof(p->cid_num));
3146
		sizeof(p->cid_num));
3139
	ast_copy_string(p->cid_name,
3147
	ast_copy_string(p->cid_name,
3140
		S_COR(caller->id.name.valid, caller->id.name.str, ""),
3148
		S_COR(caller->id.name.valid, caller->id.name.str, ""),
3141
		sizeof(p->cid_name));
3149
		sizeof(p->cid_name));
3142
	ast_copy_string(p->cid_subaddr,
3150
	ast_copy_string(p->cid_subaddr,
3143
		S_COR(caller->id.subaddress.valid, caller->id.subaddress.str, ""),
3151
		S_COR(caller->id.subaddress.valid, caller->id.subaddress.str, ""),
3144
		sizeof(p->cid_subaddr));
3152
		sizeof(p->cid_subaddr));
3145
	p->cid_ton = caller->id.number.plan;
3153
	p->cid_ton = caller->id.number.plan;
3146
	p->callingpres = ast_party_id_presentation(&caller->id);
3154
	p->callingpres = ast_party_id_presentation(&caller->id);
3147
	if (caller->id.tag) {
3155
	if (caller->id.tag) {
3148
		ast_copy_string(p->cid_tag, caller->id.tag, sizeof(p->cid_tag));
3156
		ast_copy_string(p->cid_tag, caller->id.tag, sizeof(p->cid_tag));
3149
	}
3157
	}
3150
	ast_copy_string(p->cid_ani,
3158
	ast_copy_string(p->cid_ani,
3151
		S_COR(caller->ani.number.valid, caller->ani.number.str, ""),
3159
		S_COR(caller->ani.number.valid, caller->ani.number.str, ""),
3152
		sizeof(p->cid_ani));
3160
		sizeof(p->cid_ani));
3153
	p->cid_ani2 = caller->ani2;
3161
	p->cid_ani2 = caller->ani2;
3154
}
3162
}
3155
#endif	/* defined(HAVE_PRI) || defined(HAVE_SS7) */
3163
#endif	/* defined(HAVE_PRI) || defined(HAVE_SS7) */
3156

    
   
3164

   
3157
#if defined(HAVE_PRI) || defined(HAVE_SS7)
3165
#if defined(HAVE_PRI) || defined(HAVE_SS7)
3158
/*!
3166
/*!
3159
 * \internal
3167
 * \internal
3160
 * \brief Set the Dialed Number Identifier.
3168
 * \brief Set the Dialed Number Identifier.
3161
 * \since 1.8
3169
 * \since 1.8
3162
 *
3170
 *
3163
 * \param pvt DAHDI private structure
3171
 * \param pvt DAHDI private structure
3164
 * \param dnid Dialed Number Identifier string.
3172
 * \param dnid Dialed Number Identifier string.
3165
 *
3173
 *
3166
 * \return Nothing
3174
 * \return Nothing
3167
 */
3175
 */
3168
static void my_set_dnid(void *pvt, const char *dnid)
3176
static void my_set_dnid(void *pvt, const char *dnid)
3169
{
3177
{
3170
	struct dahdi_pvt *p = pvt;
3178
	struct dahdi_pvt *p = pvt;
3171

    
   
3179

   
3172
	ast_copy_string(p->dnid, dnid, sizeof(p->dnid));
3180
	ast_copy_string(p->dnid, dnid, sizeof(p->dnid));
3173
}
3181
}
3174
#endif	/* defined(HAVE_PRI) || defined(HAVE_SS7) */
3182
#endif	/* defined(HAVE_PRI) || defined(HAVE_SS7) */
3175

    
   
3183

   
3176
#if defined(HAVE_PRI)
3184
#if defined(HAVE_PRI)
3177
/*!
3185
/*!
3178
 * \internal
3186
 * \internal
3179
 * \brief Set the Redirecting Directory Number Information Service (RDNIS).
3187
 * \brief Set the Redirecting Directory Number Information Service (RDNIS).
3180
 * \since 1.8
3188
 * \since 1.8
3181
 *
3189
 *
3182
 * \param pvt DAHDI private structure
3190
 * \param pvt DAHDI private structure
3183
 * \param rdnis Redirecting Directory Number Information Service (RDNIS) string.
3191
 * \param rdnis Redirecting Directory Number Information Service (RDNIS) string.
3184
 *
3192
 *
3185
 * \return Nothing
3193
 * \return Nothing
3186
 */
3194
 */
3187
static void my_set_rdnis(void *pvt, const char *rdnis)
3195
static void my_set_rdnis(void *pvt, const char *rdnis)
3188
{
3196
{
3189
	struct dahdi_pvt *p = pvt;
3197
	struct dahdi_pvt *p = pvt;
3190

    
   
3198

   
3191
	ast_copy_string(p->rdnis, rdnis, sizeof(p->rdnis));
3199
	ast_copy_string(p->rdnis, rdnis, sizeof(p->rdnis));
3192
}
3200
}
3193
#endif	/* defined(HAVE_PRI) */
3201
#endif	/* defined(HAVE_PRI) */
3194

    
   
3202

   
3195
#if defined(HAVE_PRI)
3203
#if defined(HAVE_PRI)
3196
/*!
3204
/*!
3197
 * \internal
3205
 * \internal
3198
 * \brief Make a dialstring for native ISDN CC to recall properly.
3206
 * \brief Make a dialstring for native ISDN CC to recall properly.
3199
 * \since 1.8
3207
 * \since 1.8
3200
 *
3208
 *
3201
 * \param priv Channel private control structure.
3209
 * \param priv Channel private control structure.
3202
 * \param buf Where to put the modified dialstring.
3210
 * \param buf Where to put the modified dialstring.
3203
 * \param buf_size Size of modified dialstring buffer.
3211
 * \param buf_size Size of modified dialstring buffer.
3204
 *
3212
 *
3205
 * \details
3213
 * \details
3206
 * original dialstring:
3214
 * original dialstring:
3207
 * DAHDI/[i<span>-](g|G|r|R)<group#(0-63)>[c|r<cadance#>|d][/extension[/options]]
3215
 * DAHDI/[i<span>-](g|G|r|R)<group#(0-63)>[c|r<cadance#>|d][/extension[/options]]
3208
 *
3216
 *
3209
 * The modified dialstring will have prefixed the channel-group section
3217
 * The modified dialstring will have prefixed the channel-group section
3210
 * with the ISDN channel restriction.
3218
 * with the ISDN channel restriction.
3211
 *
3219
 *
3212
 * buf:
3220
 * buf:
3213
 * DAHDI/i<span>-(g|G|r|R)<group#(0-63)>[c|r<cadance#>|d][/extension[/options]]
3221
 * DAHDI/i<span>-(g|G|r|R)<group#(0-63)>[c|r<cadance#>|d][/extension[/options]]
3214
 *
3222
 *
3215
 * The routine will check to see if the ISDN channel restriction is already
3223
 * The routine will check to see if the ISDN channel restriction is already
3216
 * in the original dialstring.
3224
 * in the original dialstring.
3217
 *
3225
 *
3218
 * \return Nothing
3226
 * \return Nothing
3219
 */
3227
 */
3220
static void my_pri_make_cc_dialstring(void *priv, char *buf, size_t buf_size)
3228
static void my_pri_make_cc_dialstring(void *priv, char *buf, size_t buf_size)
3221
{
3229
{
3222
	char *dial;
3230
	char *dial;
3223
	struct dahdi_pvt *pvt;
3231
	struct dahdi_pvt *pvt;
3224
	AST_DECLARE_APP_ARGS(args,
3232
	AST_DECLARE_APP_ARGS(args,
3225
		AST_APP_ARG(tech);	/* channel technology token */
3233
		AST_APP_ARG(tech);	/* channel technology token */
3226
		AST_APP_ARG(group);	/* channel/group token */
3234
		AST_APP_ARG(group);	/* channel/group token */
3227
		//AST_APP_ARG(ext);	/* extension token */
3235
		//AST_APP_ARG(ext);	/* extension token */
3228
		//AST_APP_ARG(opts);	/* options token */
3236
		//AST_APP_ARG(opts);	/* options token */
3229
		//AST_APP_ARG(other);	/* Any remining unused arguments */
3237
		//AST_APP_ARG(other);	/* Any remining unused arguments */
3230
	);
3238
	);
3231

    
   
3239

   
3232
	pvt = priv;
3240
	pvt = priv;
3233
	dial = ast_strdupa(pvt->dialstring);
3241
	dial = ast_strdupa(pvt->dialstring);
3234
	AST_NONSTANDARD_APP_ARGS(args, dial, '/');
3242
	AST_NONSTANDARD_APP_ARGS(args, dial, '/');
3235
	if (!args.tech) {
3243
	if (!args.tech) {
3236
		ast_copy_string(buf, pvt->dialstring, buf_size);
3244
		ast_copy_string(buf, pvt->dialstring, buf_size);
3237
		return;
3245
		return;
3238
	}
3246
	}
3239
	if (!args.group) {
3247
	if (!args.group) {
3240
		/* Append the ISDN span channel restriction to the dialstring. */
3248
		/* Append the ISDN span channel restriction to the dialstring. */
3241
		snprintf(buf, buf_size, "%s/i%d-", args.tech, pvt->pri->span);
3249
		snprintf(buf, buf_size, "%s/i%d-", args.tech, pvt->pri->span);
3242
		return;
3250
		return;
3243
	}
3251
	}
3244
	if (isdigit(args.group[0]) || args.group[0] == 'i' || strchr(args.group, '!')) {
3252
	if (isdigit(args.group[0]) || args.group[0] == 'i' || strchr(args.group, '!')) {
3245
		/* The ISDN span channel restriction is not needed or already
3253
		/* The ISDN span channel restriction is not needed or already
3246
		 * in the dialstring. */
3254
		 * in the dialstring. */
3247
		ast_copy_string(buf, pvt->dialstring, buf_size);
3255
		ast_copy_string(buf, pvt->dialstring, buf_size);
3248
		return;
3256
		return;
3249
	}
3257
	}
3250
	/* Insert the ISDN span channel restriction into the dialstring. */
3258
	/* Insert the ISDN span channel restriction into the dialstring. */
3251
	snprintf(buf, buf_size, "%s/i%d-%s", args.tech, pvt->pri->span, args.group);
3259
	snprintf(buf, buf_size, "%s/i%d-%s", args.tech, pvt->pri->span, args.group);
3252
}
3260
}
3253
#endif	/* defined(HAVE_PRI) */
3261
#endif	/* defined(HAVE_PRI) */
3254

    
   
3262

   
3255
#if defined(HAVE_PRI)
3263
#if defined(HAVE_PRI)
3256
/*!
3264
/*!
3257
 * \internal
3265
 * \internal
3258
 * \brief Reevaluate the PRI span device state.
3266
 * \brief Reevaluate the PRI span device state.
3259
 * \since 1.8
3267
 * \since 1.8
3260
 *
3268
 *
3261
 * \param pri Asterisk D channel control structure.
3269
 * \param pri Asterisk D channel control structure.
3262
 *
3270
 *
3263
 * \return Nothing
3271
 * \return Nothing
3264
 *
3272
 *
3265
 * \note Assumes the pri->lock is already obtained.
3273
 * \note Assumes the pri->lock is already obtained.
3266
 */
3274
 */
3267
static void dahdi_pri_update_span_devstate(struct sig_pri_span *pri)
3275
static void dahdi_pri_update_span_devstate(struct sig_pri_span *pri)
3268
{
3276
{
3269
	unsigned idx;
3277
	unsigned idx;
3270
	unsigned num_b_chans;	/* Number of B channels provisioned on the span. */
3278
	unsigned num_b_chans;	/* Number of B channels provisioned on the span. */
3271
	unsigned in_use;		/* Number of B channels in use on the span. */
3279
	unsigned in_use;		/* Number of B channels in use on the span. */
3272
	unsigned in_alarm;		/* TRUE if the span is in alarm condition. */
3280
	unsigned in_alarm;		/* TRUE if the span is in alarm condition. */
3273
	enum ast_device_state new_state;
3281
	enum ast_device_state new_state;
3274

    
   
3282

   
3275
	/* Count the number of B channels and the number of B channels in use. */
3283
	/* Count the number of B channels and the number of B channels in use. */
3276
	num_b_chans = 0;
3284
	num_b_chans = 0;
3277
	in_use = 0;
3285
	in_use = 0;
3278
	in_alarm = 1;
3286
	in_alarm = 1;
3279
	for (idx = pri->numchans; idx--;) {
3287
	for (idx = pri->numchans; idx--;) {
3280
		if (pri->pvts[idx] && !pri->pvts[idx]->no_b_channel) {
3288
		if (pri->pvts[idx] && !pri->pvts[idx]->no_b_channel) {
3281
			/* This is a B channel interface. */
3289
			/* This is a B channel interface. */
3282
			++num_b_chans;
3290
			++num_b_chans;
3283
			if (!sig_pri_is_chan_available(pri->pvts[idx])) {
3291
			if (!sig_pri_is_chan_available(pri->pvts[idx])) {
3284
				++in_use;
3292
				++in_use;
3285
			}
3293
			}
3286
			if (!pri->pvts[idx]->inalarm) {
3294
			if (!pri->pvts[idx]->inalarm) {
3287
				/* There is a channel that is not in alarm. */
3295
				/* There is a channel that is not in alarm. */
3288
				in_alarm = 0;
3296
				in_alarm = 0;
3289
			}
3297
			}
3290
		}
3298
		}
3291
	}
3299
	}
3292

    
   
3300

   
3293
	/* Update the span congestion device state and report any change. */
3301
	/* Update the span congestion device state and report any change. */
3294
	if (in_alarm) {
3302
	if (in_alarm) {
3295
		new_state = AST_DEVICE_UNAVAILABLE;
3303
		new_state = AST_DEVICE_UNAVAILABLE;
3296
	} else {
3304
	} else {
3297
		new_state = num_b_chans == in_use ? AST_DEVICE_BUSY : AST_DEVICE_NOT_INUSE;
3305
		new_state = num_b_chans == in_use ? AST_DEVICE_BUSY : AST_DEVICE_NOT_INUSE;
3298
	}
3306
	}
3299
	if (pri->congestion_devstate != new_state) {
3307
	if (pri->congestion_devstate != new_state) {
3300
		pri->congestion_devstate = new_state;
3308
		pri->congestion_devstate = new_state;
3301
		ast_devstate_changed(AST_DEVICE_UNKNOWN, "DAHDI/I%d/congestion", pri->span);
3309
		ast_devstate_changed(AST_DEVICE_UNKNOWN, "DAHDI/I%d/congestion", pri->span);
3302
	}
3310
	}
3303
#if defined(THRESHOLD_DEVSTATE_PLACEHOLDER)
3311
#if defined(THRESHOLD_DEVSTATE_PLACEHOLDER)
3304
	/* Update the span threshold device state and report any change. */
3312
	/* Update the span threshold device state and report any change. */
3305
	if (in_alarm) {
3313
	if (in_alarm) {
3306
		new_state = AST_DEVICE_UNAVAILABLE;
3314
		new_state = AST_DEVICE_UNAVAILABLE;
3307
	} else if (!in_use) {
3315
	} else if (!in_use) {
3308
		new_state = AST_DEVICE_NOT_INUSE;
3316
		new_state = AST_DEVICE_NOT_INUSE;
3309
	} else if (!pri->user_busy_threshold) {
3317
	} else if (!pri->user_busy_threshold) {
3310
		new_state = in_use < num_b_chans ? AST_DEVICE_INUSE : AST_DEVICE_BUSY;
3318
		new_state = in_use < num_b_chans ? AST_DEVICE_INUSE : AST_DEVICE_BUSY;
3311
	} else {
3319
	} else {
3312
		new_state = in_use < pri->user_busy_threshold ? AST_DEVICE_INUSE
3320
		new_state = in_use < pri->user_busy_threshold ? AST_DEVICE_INUSE
3313
			: AST_DEVICE_BUSY;
3321
			: AST_DEVICE_BUSY;
3314
	}
3322
	}
3315
	if (pri->threshold_devstate != new_state) {
3323
	if (pri->threshold_devstate != new_state) {
3316
		pri->threshold_devstate = new_state;
3324
		pri->threshold_devstate = new_state;
3317
		ast_devstate_changed(AST_DEVICE_UNKNOWN, "DAHDI/I%d/threshold", pri->span);
3325
		ast_devstate_changed(AST_DEVICE_UNKNOWN, "DAHDI/I%d/threshold", pri->span);
3318
	}
3326
	}
3319
#endif	/* defined(THRESHOLD_DEVSTATE_PLACEHOLDER) */
3327
#endif	/* defined(THRESHOLD_DEVSTATE_PLACEHOLDER) */
3320
}
3328
}
3321
#endif	/* defined(HAVE_PRI) */
3329
#endif	/* defined(HAVE_PRI) */
3322

    
   
3330

   
3323
#if defined(HAVE_PRI)
3331
#if defined(HAVE_PRI)
3324
/*!
3332
/*!
3325
 * \internal
3333
 * \internal
3326
 * \brief Reference this module.
3334
 * \brief Reference this module.
3327
 * \since 1.8
3335
 * \since 1.8
3328
 *
3336
 *
3329
 * \return Nothing
3337
 * \return Nothing
3330
 */
3338
 */
3331
static void my_module_ref(void)
3339
static void my_module_ref(void)
3332
{
3340
{
3333
	ast_module_ref(ast_module_info->self);
3341
	ast_module_ref(ast_module_info->self);
3334
}
3342
}
3335
#endif	/* defined(HAVE_PRI) */
3343
#endif	/* defined(HAVE_PRI) */
3336

    
   
3344

   
3337
#if defined(HAVE_PRI)
3345
#if defined(HAVE_PRI)
3338
/*!
3346
/*!
3339
 * \internal
3347
 * \internal
3340
 * \brief Unreference this module.
3348
 * \brief Unreference this module.
3341
 * \since 1.8
3349
 * \since 1.8
3342
 *
3350
 *
3343
 * \return Nothing
3351
 * \return Nothing
3344
 */
3352
 */
3345
static void my_module_unref(void)
3353
static void my_module_unref(void)
3346
{
3354
{
3347
	ast_module_unref(ast_module_info->self);
3355
	ast_module_unref(ast_module_info->self);
3348
}
3356
}
3349
#endif	/* defined(HAVE_PRI) */
3357
#endif	/* defined(HAVE_PRI) */
3350

    
   
3358

   
3351
#if defined(HAVE_PRI)
3359
#if defined(HAVE_PRI)
3352
#if defined(HAVE_PRI_CALL_WAITING)
3360
#if defined(HAVE_PRI_CALL_WAITING)
3353
static void my_pri_init_config(void *priv, struct sig_pri_span *pri);
3361
static void my_pri_init_config(void *priv, struct sig_pri_span *pri);
3354
#endif	/* defined(HAVE_PRI_CALL_WAITING) */
3362
#endif	/* defined(HAVE_PRI_CALL_WAITING) */
3355
static int dahdi_new_pri_nobch_channel(struct sig_pri_span *pri);
3363
static int dahdi_new_pri_nobch_channel(struct sig_pri_span *pri);
3356

    
   
3364

   
3357
static struct sig_pri_callback dahdi_pri_callbacks =
3365
static struct sig_pri_callback dahdi_pri_callbacks =
3358
{
3366
{
3359
	.handle_dchan_exception = my_handle_dchan_exception,
3367
	.handle_dchan_exception = my_handle_dchan_exception,
3360
	.play_tone = my_pri_play_tone,
3368
	.play_tone = my_pri_play_tone,
3361
	.set_echocanceller = my_set_echocanceller,
3369
	.set_echocanceller = my_set_echocanceller,
3362
	.dsp_reset_and_flush_digits = my_dsp_reset_and_flush_digits,
3370
	.dsp_reset_and_flush_digits = my_dsp_reset_and_flush_digits,
3363
	.lock_private = my_lock_private,
3371
	.lock_private = my_lock_private,
3364
	.unlock_private = my_unlock_private,
3372
	.unlock_private = my_unlock_private,
3365
	.deadlock_avoidance_private = my_deadlock_avoidance_private,
3373
	.deadlock_avoidance_private = my_deadlock_avoidance_private,
3366
	.new_ast_channel = my_new_pri_ast_channel,
3374
	.new_ast_channel = my_new_pri_ast_channel,
3367
	.fixup_chans = my_pri_fixup_chans,
3375
	.fixup_chans = my_pri_fixup_chans,
3368
	.set_alarm = my_set_alarm,
3376
	.set_alarm = my_set_alarm,
3369
	.set_dialing = my_set_dialing,
3377
	.set_dialing = my_set_dialing,
3370
	.set_digital = my_set_digital,
3378
	.set_digital = my_set_digital,
3371
	.set_callerid = my_set_callerid,
3379
	.set_callerid = my_set_callerid,
3372
	.set_dnid = my_set_dnid,
3380
	.set_dnid = my_set_dnid,
3373
	.set_rdnis = my_set_rdnis,
3381
	.set_rdnis = my_set_rdnis,
3374
	.new_nobch_intf = dahdi_new_pri_nobch_channel,
3382
	.new_nobch_intf = dahdi_new_pri_nobch_channel,
3375
#if defined(HAVE_PRI_CALL_WAITING)
3383
#if defined(HAVE_PRI_CALL_WAITING)
3376
	.init_config = my_pri_init_config,
3384
	.init_config = my_pri_init_config,
3377
#endif	/* defined(HAVE_PRI_CALL_WAITING) */
3385
#endif	/* defined(HAVE_PRI_CALL_WAITING) */
3378
	.get_orig_dialstring = my_get_orig_dialstring,
3386
	.get_orig_dialstring = my_get_orig_dialstring,
3379
	.make_cc_dialstring = my_pri_make_cc_dialstring,
3387
	.make_cc_dialstring = my_pri_make_cc_dialstring,
3380
	.update_span_devstate = dahdi_pri_update_span_devstate,
3388
	.update_span_devstate = dahdi_pri_update_span_devstate,
3381
	.module_ref = my_module_ref,
3389
	.module_ref = my_module_ref,
3382
	.module_unref = my_module_unref,
3390
	.module_unref = my_module_unref,
3383
	.open_media = my_pri_open_media,
3391
	.open_media = my_pri_open_media,
3384
	.ami_channel_event = my_ami_channel_event,
3392
	.ami_channel_event = my_ami_channel_event,
3385
};
3393
};
3386
#endif	/* defined(HAVE_PRI) */
3394
#endif	/* defined(HAVE_PRI) */
3387

    
   
3395

   
3388
#if defined(HAVE_SS7)
3396
#if defined(HAVE_SS7)
3389
/*!
3397
/*!
3390
 * \internal
3398
 * \internal
3391
 * \brief Handle the SS7 link exception.
3399
 * \brief Handle the SS7 link exception.
3392
 * \since 1.8
3400
 * \since 1.8
3393
 *
3401
 *
3394
 * \param linkset Controlling linkset for the channel.
3402
 * \param linkset Controlling linkset for the channel.
3395
 * \param which Link index of the signaling channel.
3403
 * \param which Link index of the signaling channel.
3396
 *
3404
 *
3397
 * \return Nothing
3405
 * \return Nothing
3398
 */
3406
 */
3399
static void my_handle_link_exception(struct sig_ss7_linkset *linkset, int which)
3407
static void my_handle_link_exception(struct sig_ss7_linkset *linkset, int which)
3400
{
3408
{
3401
	int event;
3409
	int event;
3402

    
   
3410

   
3403
	if (ioctl(linkset->fds[which], DAHDI_GETEVENT, &event)) {
3411
	if (ioctl(linkset->fds[which], DAHDI_GETEVENT, &event)) {
3404
		ast_log(LOG_ERROR, "SS7: Error in exception retrieval on span %d/%d!\n",
3412
		ast_log(LOG_ERROR, "SS7: Error in exception retrieval on span %d/%d!\n",
3405
			linkset->span, which);
3413
			linkset->span, which);
3406
		return;
3414
		return;
3407
	}
3415
	}
3408
	switch (event) {
3416
	switch (event) {
3409
	case DAHDI_EVENT_NONE:
3417
	case DAHDI_EVENT_NONE:
3410
		break;
3418
		break;
3411
	case DAHDI_EVENT_ALARM:
3419
	case DAHDI_EVENT_ALARM:
3412
		ast_log(LOG_ERROR, "SS7 got event: %s(%d) on span %d/%d\n",
3420
		ast_log(LOG_ERROR, "SS7 got event: %s(%d) on span %d/%d\n",
3413
			event2str(event), event, linkset->span, which);
3421
			event2str(event), event, linkset->span, which);
3414
		sig_ss7_link_alarm(linkset, which);
3422
		sig_ss7_link_alarm(linkset, which);
3415
		break;
3423
		break;
3416
	case DAHDI_EVENT_NOALARM:
3424
	case DAHDI_EVENT_NOALARM:
3417
		ast_log(LOG_ERROR, "SS7 got event: %s(%d) on span %d/%d\n",
3425
		ast_log(LOG_ERROR, "SS7 got event: %s(%d) on span %d/%d\n",
3418
			event2str(event), event, linkset->span, which);
3426
			event2str(event), event, linkset->span, which);
3419
		sig_ss7_link_noalarm(linkset, which);
3427
		sig_ss7_link_noalarm(linkset, which);
3420
		break;
3428
		break;
3421
	default:
3429
	default:
3422
		ast_log(LOG_NOTICE, "SS7 got event: %s(%d) on span %d/%d\n",
3430
		ast_log(LOG_NOTICE, "SS7 got event: %s(%d) on span %d/%d\n",
3423
			event2str(event), event, linkset->span, which);
3431
			event2str(event), event, linkset->span, which);
3424
		break;
3432
		break;
3425
	}
3433
	}
3426
}
3434
}
3427
#endif	/* defined(HAVE_SS7) */
3435
#endif	/* defined(HAVE_SS7) */
3428

    
   
3436

   
3429
#if defined(HAVE_SS7)
3437
#if defined(HAVE_SS7)
3430
static void my_ss7_set_loopback(void *pvt, int enable)
3438
static void my_ss7_set_loopback(void *pvt, int enable)
3431
{
3439
{
3432
	struct dahdi_pvt *p = pvt;
3440
	struct dahdi_pvt *p = pvt;
3433

    
   
3441

   
3434
	if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_LOOPBACK, &enable)) {
3442
	if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_LOOPBACK, &enable)) {
3435
		ast_log(LOG_WARNING, "Unable to set loopback on channel %d: %s\n", p->channel,
3443
		ast_log(LOG_WARNING, "Unable to set loopback on channel %d: %s\n", p->channel,
3436
			strerror(errno));
3444
			strerror(errno));
3437
	}
3445
	}
3438
}
3446
}
3439
#endif	/* defined(HAVE_SS7) */
3447
#endif	/* defined(HAVE_SS7) */
3440

    
   
3448

   
3441
#if defined(HAVE_SS7)
3449
#if defined(HAVE_SS7)
3442
/*!
3450
/*!
3443
 * \internal
3451
 * \internal
3444
 * \brief Create a new asterisk channel structure for SS7.
3452
 * \brief Create a new asterisk channel structure for SS7.
3445
 * \since 1.8
3453
 * \since 1.8
3446
 *
3454
 *
3447
 * \param pvt Private channel structure.
3455
 * \param pvt Private channel structure.
3448
 * \param state Initial state of new channel.
3456
 * \param state Initial state of new channel.
3449
 * \param law Combanding law to use.
3457
 * \param law Combanding law to use.
3450
 * \param exten Dialplan extension for incoming call.
3458
 * \param exten Dialplan extension for incoming call.
3451
 * \param requestor Channel requesting this new channel.
3459
 * \param requestor Channel requesting this new channel.
3452
 *
3460
 *
3453
 * \retval ast_channel on success.
3461
 * \retval ast_channel on success.
3454
 * \retval NULL on error.
3462
 * \retval NULL on error.
3455
 */
3463
 */
3456
static struct ast_channel *my_new_ss7_ast_channel(void *pvt, int state, enum sig_ss7_law law, char *exten, const struct ast_channel *requestor)
3464
static struct ast_channel *my_new_ss7_ast_channel(void *pvt, int state, enum sig_ss7_law law, char *exten, const struct ast_channel *requestor)
3457
{
3465
{
3458
	struct dahdi_pvt *p = pvt;
3466
	struct dahdi_pvt *p = pvt;
3459
	int audio;
3467
	int audio;
3460
	int newlaw;
3468
	int newlaw;
3461

    
   
3469

   
3462
	/* Set to audio mode at this point */
3470
	/* Set to audio mode at this point */
3463
	audio = 1;
3471
	audio = 1;
3464
	if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &audio) == -1)
3472
	if (ioctl(p->subs[SUB_REAL].dfd, DAHDI_AUDIOMODE, &audio) == -1)
3465
		ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d: %s\n",
3473
		ast_log(LOG_WARNING, "Unable to set audio mode on channel %d to %d: %s\n",
3466
			p->channel, audio, strerror(errno));
3474
			p->channel, audio, strerror(errno));
3467

    
   
3475

   
3468
	if (law != SIG_SS7_DEFLAW) {
3476
	if (law != SIG_SS7_DEFLAW) {
3469
		dahdi_setlaw(p->subs[SUB_REAL].dfd,
3477
		dahdi_setlaw(p->subs[SUB_REAL].dfd,
3470
			(law == SIG_SS7_ULAW) ? DAHDI_LAW_MULAW : DAHDI_LAW_ALAW);
3478
			(law == SIG_SS7_ULAW) ? DAHDI_LAW_MULAW : DAHDI_LAW_ALAW);
3471
	}
3479
	}
3472

    
   
3480

   
3473
	ast_copy_string(p->exten, exten, sizeof(p->exten));
3481
	ast_copy_string(p->exten, exten, sizeof(p->exten));
3474

    
   
3482

   
3475
	newlaw = -1;
3483
	newlaw = -1;
3476
	switch (law) {
3484
	switch (law) {
3477
	case SIG_SS7_DEFLAW:
3485
	case SIG_SS7_DEFLAW:
3478
		newlaw = 0;
3486
		newlaw = 0;
3479
		break;
3487
		break;
3480
	case SIG_SS7_ALAW:
3488
	case SIG_SS7_ALAW:
3481
		newlaw = DAHDI_LAW_ALAW;
3489
		newlaw = DAHDI_LAW_ALAW;
3482
		break;
3490
		break;
3483
	case SIG_SS7_ULAW:
3491
	case SIG_SS7_ULAW:
3484
		newlaw = DAHDI_LAW_MULAW;
3492
		newlaw = DAHDI_LAW_MULAW;
3485
		break;
3493
		break;
3486
	}
3494
	}
3487
	return dahdi_new(p, state, 0, SUB_REAL, newlaw, requestor ? ast_channel_linkedid(requestor) : "");
3495
	return dahdi_new(p, state, 0, SUB_REAL, newlaw, requestor ? ast_channel_linkedid(requestor) : "");
3488
}
3496
}
3489
#endif	/* defined(HAVE_SS7) */
3497
#endif	/* defined(HAVE_SS7) */
3490

    
   
3498

   
3491
#if defined(HAVE_SS7)
3499
#if defined(HAVE_SS7)
3492
static int sig_ss7_tone_to_dahditone(enum sig_ss7_tone tone)
3500
static int sig_ss7_tone_to_dahditone(enum sig_ss7_tone tone)
3493
{
3501
{
3494
	switch (tone) {
3502
	switch (tone) {
3495
	case SIG_SS7_TONE_RINGTONE:
3503
	case SIG_SS7_TONE_RINGTONE:
3496
		return DAHDI_TONE_RINGTONE;
3504
		return DAHDI_TONE_RINGTONE;
3497
	case SIG_SS7_TONE_STUTTER:
3505
	case SIG_SS7_TONE_STUTTER:
3498
		return DAHDI_TONE_STUTTER;
3506
		return DAHDI_TONE_STUTTER;
3499
	case SIG_SS7_TONE_CONGESTION:
3507
	case SIG_SS7_TONE_CONGESTION:
3500
		return DAHDI_TONE_CONGESTION;
3508
		return DAHDI_TONE_CONGESTION;
3501
	case SIG_SS7_TONE_DIALTONE:
3509
	case SIG_SS7_TONE_DIALTONE:
3502
		return DAHDI_TONE_DIALTONE;
3510
		return DAHDI_TONE_DIALTONE;
3503
	case SIG_SS7_TONE_DIALRECALL:
3511
	case SIG_SS7_TONE_DIALRECALL:
3504
		return DAHDI_TONE_DIALRECALL;
3512
		return DAHDI_TONE_DIALRECALL;
3505
	case SIG_SS7_TONE_INFO:
3513
	case SIG_SS7_TONE_INFO:
3506
		return DAHDI_TONE_INFO;
3514
		return DAHDI_TONE_INFO;
3507
	case SIG_SS7_TONE_BUSY:
3515
	case SIG_SS7_TONE_BUSY:
3508
		return DAHDI_TONE_BUSY;
3516
		return DAHDI_TONE_BUSY;
3509
	default:
3517
	default:
3510
		return -1;
3518
		return -1;
3511
	}
3519
	}
3512
}
3520
}
3513
#endif	/* defined(HAVE_SS7) */
3521
#endif	/* defined(HAVE_SS7) */
3514

    
   
3522

   
3515
#if defined(HAVE_SS7)
3523
#if defined(HAVE_SS7)
3516
static int my_ss7_play_tone(void *pvt, enum sig_ss7_tone tone)
3524
static int my_ss7_play_tone(void *pvt, enum sig_ss7_tone tone)
3517
{
3525
{
3518
	struct dahdi_pvt *p = pvt;
3526
	struct dahdi_pvt *p = pvt;
3519

    
   
3527

   
3520
	return tone_zone_play_tone(p->subs[SUB_REAL].dfd, sig_ss7_tone_to_dahditone(tone));
3528
	return tone_zone_play_tone(p->subs[SUB_REAL].dfd, sig_ss7_tone_to_dahditone(tone));
3521
}
3529
}
3522
#endif	/* defined(HAVE_SS7) */
3530
#endif	/* defined(HAVE_SS7) */
3523

    
   
3531

   
3524
#if defined(HAVE_SS7)
3532
#if defined(HAVE_SS7)
3525
static struct sig_ss7_callback dahdi_ss7_callbacks =
3533
static struct sig_ss7_callback dahdi_ss7_callbacks =
3526
{
3534
{
3527
	.lock_private = my_lock_private,
3535
	.lock_private = my_lock_private,
3528
	.unlock_private = my_unlock_private,
3536
	.unlock_private = my_unlock_private,
3529
	.deadlock_avoidance_private = my_deadlock_avoidance_private,
3537
	.deadlock_avoidance_private = my_deadlock_avoidance_private,
3530

    
   
3538

   
3531
	.set_echocanceller = my_set_echocanceller,
3539
	.set_echocanceller = my_set_echocanceller,
3532
	.set_loopback = my_ss7_set_loopback,
3540
	.set_loopback = my_ss7_set_loopback,
3533

    
   
3541

   
3534
	.new_ast_channel = my_new_ss7_ast_channel,
3542
	.new_ast_channel = my_new_ss7_ast_channel,
3535
	.play_tone = my_ss7_play_tone,
3543
	.play_tone = my_ss7_play_tone,
3536

    
   
3544

   
3537
	.handle_link_exception = my_handle_link_exception,
3545
	.handle_link_exception = my_handle_link_exception,
3538
	.set_alarm = my_set_alarm,
3546
	.set_alarm = my_set_alarm,
3539
	.set_dialing = my_set_dialing,
3547
	.set_dialing = my_set_dialing,
3540
	.set_digital = my_set_digital,
3548
	.set_digital = my_set_digital,
3541
	.set_inservice = my_set_inservice,
3549
	.set_inservice = my_set_inservice,
3542
	.set_locallyblocked = my_set_locallyblocked,
3550
	.set_locallyblocked = my_set_locallyblocked,
3543
	.set_remotelyblocked = my_set_remotelyblocked,
3551
	.set_remotelyblocked = my_set_remotelyblocked,
3544
	.set_callerid = my_set_callerid,
3552
	.set_callerid = my_set_callerid,
3545
	.set_dnid = my_set_dnid,
3553
	.set_dnid = my_set_dnid,
3546
};
3554
};
3547
#endif	/* defined(HAVE_SS7) */
3555
#endif	/* defined(HAVE_SS7) */
3548

    
   
3556

   
3549
/*!
3557
/*!
3550
 * \brief Send MWI state change
3558
 * \brief Send MWI state change
3551
 *
3559
 *
3552
 * \arg mailbox_full This is the mailbox associated with the FXO line that the
3560
 * \arg mailbox_full This is the mailbox associated with the FXO line that the
3553
 *      MWI state has changed on.
3561
 *      MWI state has changed on.
3554
 * \arg thereornot This argument should simply be set to 1 or 0, to indicate
3562
 * \arg thereornot This argument should simply be set to 1 or 0, to indicate
3555
 *      whether there are messages waiting or not.
3563
 *      whether there are messages waiting or not.
3556
 *
3564
 *
3557
 *  \return nothing
3565
 *  \return nothing
3558
 *
3566
 *
3559
 * This function does two things:
3567
 * This function does two things:
3560
 *
3568
 *
3561
 * 1) It generates an internal Asterisk event notifying any other module that
3569
 * 1) It generates an internal Asterisk event notifying any other module that
3562
 *    cares about MWI that the state of a mailbox has changed.
3570
 *    cares about MWI that the state of a mailbox has changed.
3563
 *
3571
 *
3564
 * 2) It runs the script specified by the mwimonitornotify option to allow
3572
 * 2) It runs the script specified by the mwimonitornotify option to allow
3565
 *    some custom handling of the state change.
3573
 *    some custom handling of the state change.
3566
 */
3574
 */
3567
static void notify_message(char *mailbox_full, int thereornot)
3575
static void notify_message(char *mailbox_full, int thereornot)
3568
{
3576
{
3569
	char s[sizeof(mwimonitornotify) + 80];
3577
	char s[sizeof(mwimonitornotify) + 80];
3570
	struct ast_event *event;
3578
	struct ast_event *event;
3571
	char *mailbox, *context;
3579
	char *mailbox, *context;
3572

    
   
3580

   
3573
	/* Strip off @default */
3581
	/* Strip off @default */
3574
	context = mailbox = ast_strdupa(mailbox_full);
3582
	context = mailbox = ast_strdupa(mailbox_full);
3575
	strsep(&context, "@");
3583
	strsep(&context, "@");
3576
	if (ast_strlen_zero(context))
3584
	if (ast_strlen_zero(context))
3577
		context = "default";
3585
		context = "default";
3578

    
   
3586

   
3579
	if (!(event = ast_event_new(AST_EVENT_MWI,
3587
	if (!(event = ast_event_new(AST_EVENT_MWI,
3580
			AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
3588
			AST_EVENT_IE_MAILBOX, AST_EVENT_IE_PLTYPE_STR, mailbox,
3581
			AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
3589
			AST_EVENT_IE_CONTEXT, AST_EVENT_IE_PLTYPE_STR, context,
3582
			AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, thereornot,
3590
			AST_EVENT_IE_NEWMSGS, AST_EVENT_IE_PLTYPE_UINT, thereornot,
3583
			AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, thereornot,
3591
			AST_EVENT_IE_OLDMSGS, AST_EVENT_IE_PLTYPE_UINT, thereornot,
3584
			AST_EVENT_IE_END))) {
3592
			AST_EVENT_IE_END))) {
3585
		return;
3593
		return;
3586
	}
3594
	}
3587

    
   
3595

   
3588
	ast_event_queue_and_cache(event);
3596
	ast_event_queue_and_cache(event);
3589

    
   
3597

   
3590
	if (!ast_strlen_zero(mailbox) && !ast_strlen_zero(mwimonitornotify)) {
3598
	if (!ast_strlen_zero(mailbox) && !ast_strlen_zero(mwimonitornotify)) {
3591
		snprintf(s, sizeof(s), "%s %s %d", mwimonitornotify, mailbox, thereornot);
3599
		snprintf(s, sizeof(s), "%s %s %d", mwimonitornotify, mailbox, thereornot);
3592
		ast_safe_system(s);
3600
		ast_safe_system(s);
3593
	}
3601
	}
3594
}
3602
}
3595

    
   
3603

   
3596
static void my_handle_notify_message(struct ast_channel *chan, void *pvt, int cid_flags, int neon_mwievent)
3604
static void my_handle_notify_message(struct ast_channel *chan, void *pvt, int cid_flags, int neon_mwievent)
3597
{
3605
{
3598
	struct dahdi_pvt *p = pvt;
3606
	struct dahdi_pvt *p = pvt;
3599

    
   
3607

   
3600
	if (neon_mwievent > -1 && !p->mwimonitor_neon)
3608
	if (neon_mwievent > -1 && !p->mwimonitor_neon)
3601
		return;
3609
		return;
3602

    
   
3610

   
3603
	if (neon_mwievent == ANALOG_EVENT_NEONMWI_ACTIVE || cid_flags & CID_MSGWAITING) {
3611
	if (neon_mwievent == ANALOG_EVENT_NEONMWI_ACTIVE || cid_flags & CID_MSGWAITING) {
3604
		ast_log(LOG_NOTICE, "MWI: Channel %d message waiting, mailbox %s\n", p->channel, p->mailbox);
3612
		ast_log(LOG_NOTICE, "MWI: Channel %d message waiting, mailbox %s\n", p->channel, p->mailbox);
3605
		notify_message(p->mailbox, 1);
3613
		notify_message(p->mailbox, 1);
3606
	} else if (neon_mwievent == ANALOG_EVENT_NEONMWI_INACTIVE || cid_flags & CID_NOMSGWAITING) {
3614
	} else if (neon_mwievent == ANALOG_EVENT_NEONMWI_INACTIVE || cid_flags & CID_NOMSGWAITING) {
3607
		ast_log(LOG_NOTICE, "MWI: Channel %d no message waiting, mailbox %s\n", p->channel, p->mailbox);
3615
		ast_log(LOG_NOTICE, "MWI: Channel %d no message waiting, mailbox %s\n", p->channel, p->mailbox);
3608
		notify_message(p->mailbox, 0);
3616
		notify_message(p->mailbox, 0);
3609
	}
3617
	}
3610
	/* If the CID had Message waiting payload, assume that this for MWI only and hangup the call */
3618
	/* If the CID had Message waiting payload, assume that this for MWI only and hangup the call */
3611
	/* If generated using Ring Pulse Alert, then ring has been answered as a call and needs to be hungup */
3619
	/* If generated using Ring Pulse Alert, then ring has been answered as a call and needs to be hungup */
3612
	if (neon_mwievent == -1 && p->mwimonitor_rpas) {
3620
	if (neon_mwievent == -1 && p->mwimonitor_rpas) {
3613
		ast_hangup(chan);
3621
		ast_hangup(chan);
3614
		return;
3622
		return;
3615
	}
3623
	}
3616
}
3624
}
3617

    
   
3625

   
3618
static int my_have_progressdetect(void *pvt)
3626
static int my_have_progressdetect(void *pvt)
3619
{
3627
{
3620
	struct dahdi_pvt *p = pvt;
3628
	struct dahdi_pvt *p = pvt;
3621

    
   
3629

   
3622
	if ((p->callprogress & CALLPROGRESS_PROGRESS)
3630
	if ((p->callprogress & CALLPROGRESS_PROGRESS)
3623
		&& CANPROGRESSDETECT(p) && p->dsp && p->outgoing) {
3631
		&& CANPROGRESSDETECT(p) && p->dsp && p->outgoing) {
3624
		return 1;
3632
		return 1;
3625
	} else {
3633
	} else {
3626
		/* Don't have progress detection. */
3634
		/* Don't have progress detection. */
3627
		return 0;
3635
		return 0;
3628
	}
3636
	}
3629
}
3637
}
3630

    
   
3638

   
3631
static struct analog_callback dahdi_analog_callbacks =
3639
static struct analog_callback dahdi_analog_callbacks =
3632
{
3640
{
3633
	.play_tone = my_play_tone,
3641
	.play_tone = my_play_tone,
3634
	.get_event = my_get_event,
3642
	.get_event = my_get_event,
3635
	.wait_event = my_wait_event,
3643
	.wait_event = my_wait_event,
3636
	.is_off_hook = my_is_off_hook,
3644
	.is_off_hook = my_is_off_hook,
3637
	.set_echocanceller = my_set_echocanceller,
3645
	.set_echocanceller = my_set_echocanceller,
3638
	.ring = my_ring,
3646
	.ring = my_ring,
3639
	.flash = my_flash,
3647
	.flash = my_flash,
3640
	.off_hook = my_off_hook,
3648
	.off_hook = my_off_hook,
3641
	.dial_digits = my_dial_digits,
3649
	.dial_digits = my_dial_digits,
3642
	.train_echocanceller = my_train_echocanceller,
3650
	.train_echocanceller = my_train_echocanceller,
3643
	.on_hook = my_on_hook,
3651
	.on_hook = my_on_hook,
3644
	.is_dialing = my_is_dialing,
3652
	.is_dialing = my_is_dialing,
3645
	.allocate_sub = my_allocate_sub,
3653
	.allocate_sub = my_allocate_sub,
3646
	.unallocate_sub = my_unallocate_sub,
3654
	.unallocate_sub = my_unallocate_sub,
3647
	.swap_subs = my_swap_subchannels,
3655
	.swap_subs = my_swap_subchannels,
3648
	.has_voicemail = my_has_voicemail,
3656
	.has_voicemail = my_has_voicemail,
3649
	.check_for_conference = my_check_for_conference,
3657
	.check_for_conference = my_check_for_conference,
3650
	.conf_add = my_conf_add,
3658
	.conf_add = my_conf_add,
3651
	.conf_del = my_conf_del,
3659
	.conf_del = my_conf_del,
3652
	.complete_conference_update = my_complete_conference_update,
3660
	.complete_conference_update = my_complete_conference_update,
3653
	.start = my_start,
3661
	.start = my_start,
3654
	.all_subchannels_hungup = my_all_subchannels_hungup,
3662
	.all_subchannels_hungup = my_all_subchannels_hungup,
3655
	.lock_private = my_lock_private,
3663
	.lock_private = my_lock_private,
3656
	.unlock_private = my_unlock_private,
3664
	.unlock_private = my_unlock_private,
3657
	.deadlock_avoidance_private = my_deadlock_avoidance_private,
3665
	.deadlock_avoidance_private = my_deadlock_avoidance_private,
3658
	.handle_dtmf = my_handle_dtmf,
3666
	.handle_dtmf = my_handle_dtmf,
3659
	.wink = my_wink,
3667
	.wink = my_wink,
3660
	.new_ast_channel = my_new_analog_ast_channel,
3668
	.new_ast_channel = my_new_analog_ast_channel,
3661
	.dsp_set_digitmode = my_dsp_set_digitmode,
3669
	.dsp_set_digitmode = my_dsp_set_digitmode,
3662
	.dsp_reset_and_flush_digits = my_dsp_reset_and_flush_digits,
3670
	.dsp_reset_and_flush_digits = my_dsp_reset_and_flush_digits,
3663
	.send_callerid = my_send_callerid,
3671
	.send_callerid = my_send_callerid,
3664
	.callwait = my_callwait,
3672
	.callwait = my_callwait,
3665
	.stop_callwait = my_stop_callwait,
3673
	.stop_callwait = my_stop_callwait,
3666
	.get_callerid = my_get_callerid,
3674
	.get_callerid = my_get_callerid,
3667
	.start_cid_detect = my_start_cid_detect,
3675
	.start_cid_detect = my_start_cid_detect,
3668
	.stop_cid_detect = my_stop_cid_detect,
3676
	.stop_cid_detect = my_stop_cid_detect,
3669
	.handle_notify_message = my_handle_notify_message,
3677
	.handle_notify_message = my_handle_notify_message,
3670
	.increase_ss_count = my_increase_ss_count,
3678
	.increase_ss_count = my_increase_ss_count,
3671
	.decrease_ss_count = my_decrease_ss_count,
3679
	.decrease_ss_count = my_decrease_ss_count,
3672
	.distinctive_ring = my_distinctive_ring,
3680
	.distinctive_ring = my_distinctive_ring,
3673
	.set_linear_mode = my_set_linear_mode,
3681
	.set_linear_mode = my_set_linear_mode,
3674
	.set_inthreeway = my_set_inthreeway,
3682
	.set_inthreeway = my_set_inthreeway,
3675
	.get_and_handle_alarms = my_get_and_handle_alarms,
3683
	.get_and_handle_alarms = my_get_and_handle_alarms,
3676
	.get_sigpvt_bridged_channel = my_get_sigpvt_bridged_channel,
3684
	.get_sigpvt_bridged_channel = my_get_sigpvt_bridged_channel,
3677
	.get_sub_fd = my_get_sub_fd,
3685
	.get_sub_fd = my_get_sub_fd,
3678
	.set_cadence = my_set_cadence,
3686
	.set_cadence = my_set_cadence,
3679
	.set_alarm = my_set_alarm,
3687
	.set_alarm = my_set_alarm,
3680
	.set_dialing = my_set_dialing,
3688
	.set_dialing = my_set_dialing,

    
   
3689
	.set_outgoing = my_set_outgoing,
3681
	.set_ringtimeout = my_set_ringtimeout,
3690
	.set_ringtimeout = my_set_ringtimeout,
3682
	.set_waitingfordt = my_set_waitingfordt,
3691
	.set_waitingfordt = my_set_waitingfordt,
3683
	.check_waitingfordt = my_check_waitingfordt,
3692
	.check_waitingfordt = my_check_waitingfordt,
3684
	.set_confirmanswer = my_set_confirmanswer,
3693
	.set_confirmanswer = my_set_confirmanswer,
3685
	.check_confirmanswer = my_check_confirmanswer,
3694
	.check_confirmanswer = my_check_confirmanswer,
3686
	.set_callwaiting = my_set_callwaiting,
3695
	.set_callwaiting = my_set_callwaiting,
3687
	.cancel_cidspill = my_cancel_cidspill,
3696
	.cancel_cidspill = my_cancel_cidspill,
3688
	.confmute = my_confmute,
3697
	.confmute = my_confmute,
3689
	.set_pulsedial = my_set_pulsedial,
3698
	.set_pulsedial = my_set_pulsedial,
3690
	.set_new_owner = my_set_new_owner,
3699
	.set_new_owner = my_set_new_owner,
3691
	.get_orig_dialstring = my_get_orig_dialstring,
3700
	.get_orig_dialstring = my_get_orig_dialstring,
3692
	.set_needringing = my_set_needringing,
3701
	.set_needringing = my_set_needringing,
3693
	.set_polarity = my_set_polarity,
3702
	.set_polarity = my_set_polarity,
3694
	.start_polarityswitch = my_start_polarityswitch,
3703
	.start_polarityswitch = my_start_polarityswitch,
3695
	.answer_polarityswitch = my_answer_polarityswitch,
3704
	.answer_polarityswitch = my_answer_polarityswitch,
3696
	.hangup_polarityswitch = my_hangup_polarityswitch,
3705
	.hangup_polarityswitch = my_hangup_polarityswitch,
3697
	.have_progressdetect = my_have_progressdetect,
3706
	.have_progressdetect = my_have_progressdetect,
3698
};
3707
};
3699

    
   
3708

   
3700
/*! Round robin search locations. */
3709
/*! Round robin search locations. */
3701
static struct dahdi_pvt *round_robin[32];
3710
static struct dahdi_pvt *round_robin[32];
3702

    
   
3711

   
3703
#define dahdi_get_index(ast, p, nullok)	_dahdi_get_index(ast, p, nullok, __PRETTY_FUNCTION__, __LINE__)
3712
#define dahdi_get_index(ast, p, nullok)	_dahdi_get_index(ast, p, nullok, __PRETTY_FUNCTION__, __LINE__)
3704
static int _dahdi_get_index(struct ast_channel *ast, struct dahdi_pvt *p, int nullok, const char *fname, unsigned long line)
3713
static int _dahdi_get_index(struct ast_channel *ast, struct dahdi_pvt *p, int nullok, const char *fname, unsigned long line)
3705
{
3714
{
3706
	int res;
3715
	int res;
3707
	if (p->subs[SUB_REAL].owner == ast)
3716
	if (p->subs[SUB_REAL].owner == ast)
3708
		res = 0;
3717
		res = 0;
3709
	else if (p->subs[SUB_CALLWAIT].owner == ast)
3718
	else if (p->subs[SUB_CALLWAIT].owner == ast)
3710
		res = 1;
3719
		res = 1;
3711
	else if (p->subs[SUB_THREEWAY].owner == ast)
3720
	else if (p->subs[SUB_THREEWAY].owner == ast)
3712
		res = 2;
3721
		res = 2;
3713
	else {
3722
	else {
3714
		res = -1;
3723
		res = -1;
3715
		if (!nullok)
3724
		if (!nullok)
3716
			ast_log(LOG_WARNING,
3725
			ast_log(LOG_WARNING,
3717
				"Unable to get index for '%s' on channel %d (%s(), line %lu)\n",
3726
				"Unable to get index for '%s' on channel %d (%s(), line %lu)\n",
3718
				ast ? ast_channel_name(ast) : "", p->channel, fname, line);
3727
				ast ? ast_channel_name(ast) : "", p->channel, fname, line);
3719
	}
3728
	}
3720
	return res;
3729
	return res;
3721
}
3730
}
3722

    
   
3731

   
3723
/*!
3732
/*!
3724
 * \internal
3733
 * \internal
3725
 * \brief Obtain the specified subchannel owner lock if the owner exists.
3734
 * \brief Obtain the specified subchannel owner lock if the owner exists.
3726
 *
3735
 *
3727
 * \param pvt Channel private struct.
3736
 * \param pvt Channel private struct.
3728
 * \param sub_idx Subchannel owner to lock.
3737
 * \param sub_idx Subchannel owner to lock.
3729
 *
3738
 *
3730
 * \note Assumes the pvt->lock is already obtained.
3739
 * \note Assumes the pvt->lock is already obtained.
3731
 *
3740
 *
3732
 * \note
3741
 * \note
3733
 * Because deadlock avoidance may have been necessary, you need to confirm
3742
 * Because deadlock avoidance may have been necessary, you need to confirm
3734
 * the state of things before continuing.
3743
 * the state of things before continuing.
3735
 *
3744
 *
3736
 * \return Nothing
3745
 * \return Nothing
3737
 */
3746
 */
3738
static void dahdi_lock_sub_owner(struct dahdi_pvt *pvt, int sub_idx)
3747
static void dahdi_lock_sub_owner(struct dahdi_pvt *pvt, int sub_idx)
3739
{
3748
{
3740
	for (;;) {
3749
	for (;;) {
3741
		if (!pvt->subs[sub_idx].owner) {
3750
		if (!pvt->subs[sub_idx].owner) {
3742
			/* No subchannel owner pointer */
3751
			/* No subchannel owner pointer */
3743
			break;
3752
			break;
3744
		}
3753
		}
3745
		if (!ast_channel_trylock(pvt->subs[sub_idx].owner)) {
3754
		if (!ast_channel_trylock(pvt->subs[sub_idx].owner)) {
3746
			/* Got subchannel owner lock */
3755
			/* Got subchannel owner lock */
3747
			break;
3756
			break;
3748
		}
3757
		}
3749
		/* We must unlock the private to avoid the possibility of a deadlock */
3758
		/* We must unlock the private to avoid the possibility of a deadlock */
3750
		DEADLOCK_AVOIDANCE(&pvt->lock);
3759
		DEADLOCK_AVOIDANCE(&pvt->lock);
3751
	}
3760
	}
3752
}
3761
}
3753

    
   
3762

   
3754
static void wakeup_sub(struct dahdi_pvt *p, int a)
3763
static void wakeup_sub(struct dahdi_pvt *p, int a)
3755
{
3764
{
3756
	dahdi_lock_sub_owner(p, a);
3765
	dahdi_lock_sub_owner(p, a);
3757
	if (p->subs[a].owner) {
3766
	if (p->subs[a].owner) {
3758
		ast_queue_frame(p->subs[a].owner, &ast_null_frame);
3767
		ast_queue_frame(p->subs[a].owner, &ast_null_frame);
3759
		ast_channel_unlock(p->subs[a].owner);
3768
		ast_channel_unlock(p->subs[a].owner);
3760
	}
3769
	}
3761
}
3770
}
3762

    
   
3771

   
3763
static void dahdi_queue_frame(struct dahdi_pvt *p, struct ast_frame *f)
3772
static void dahdi_queue_frame(struct dahdi_pvt *p, struct ast_frame *f)
3764
{
3773
{
3765
	for (;;) {
3774
	for (;;) {
3766
		if (p->owner) {
3775
		if (p->owner) {
3767
			if (ast_channel_trylock(p->owner)) {
3776
			if (ast_channel_trylock(p->owner)) {
3768
				DEADLOCK_AVOIDANCE(&p->lock);
3777
				DEADLOCK_AVOIDANCE(&p->lock);
3769
			} else {
3778
			} else {
3770
				ast_queue_frame(p->owner, f);
3779
				ast_queue_frame(p->owner, f);
3771
				ast_channel_unlock(p->owner);
3780
				ast_channel_unlock(p->owner);
3772
				break;
3781
				break;
3773
			}
3782
			}
3774
		} else
3783
		} else
3775
			break;
3784
			break;
3776
	}
3785
	}
3777
}
3786
}
3778

    
   
3787

   
3779
static void handle_clear_alarms(struct dahdi_pvt *p)
3788
static void handle_clear_alarms(struct dahdi_pvt *p)
3780
{
3789
{
3781
	if (report_alarms & REPORT_CHANNEL_ALARMS) {
3790
	if (report_alarms & REPORT_CHANNEL_ALARMS) {
3782
		ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel);
3791
		ast_log(LOG_NOTICE, "Alarm cleared on channel %d\n", p->channel);
3783
		manager_event(EVENT_FLAG_SYSTEM, "AlarmClear", "Channel: %d\r\n", p->channel);
3792
		manager_event(EVENT_FLAG_SYSTEM, "AlarmClear", "Channel: %d\r\n", p->channel);
3784
	}
3793
	}
3785
	if (report_alarms & REPORT_SPAN_ALARMS && p->manages_span_alarms) {
3794
	if (report_alarms & REPORT_SPAN_ALARMS && p->manages_span_alarms) {
3786
		ast_log(LOG_NOTICE, "Alarm cleared on span %d\n", p->span);
3795
		ast_log(LOG_NOTICE, "Alarm cleared on span %d\n", p->span);
3787
		manager_event(EVENT_FLAG_SYSTEM, "SpanAlarmClear", "Span: %d\r\n", p->span);
3796
		manager_event(EVENT_FLAG_SYSTEM, "SpanAlarmClear", "Span: %d\r\n", p->span);
3788
	}
3797
	}
3789
}
3798
}
3790

    
   
3799

   
3791
#ifdef HAVE_OPENR2
3800
#ifdef HAVE_OPENR2
3792

    
   
3801

   
3793
static int dahdi_r2_answer(struct dahdi_pvt *p)
3802
static int dahdi_r2_answer(struct dahdi_pvt *p)
3794
{
3803
{
3795
	int res = 0;
3804
	int res = 0;
3796
	/* openr2 1.1.0 and older does not even define OR2_LIB_INTERFACE
3805
	/* openr2 1.1.0 and older does not even define OR2_LIB_INTERFACE
3797
	* and does not has support for openr2_chan_answer_call_with_mode
3806
	* and does not has support for openr2_chan_answer_call_with_mode
3798
	*  */
3807
	*  */
3799
#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
3808
#if defined(OR2_LIB_INTERFACE) && OR2_LIB_INTERFACE > 1
3800
	const char *double_answer = pbx_builtin_getvar_helper(p->owner, "MFCR2_DOUBLE_ANSWER");
3809
	const char *double_answer = pbx_builtin_getvar_helper(p->owner, "MFCR2_DOUBLE_ANSWER");
3801
	int wants_double_answer = ast_true(double_answer) ? 1 : 0;
3810
	int wants_double_answer = ast_true(double_answer) ? 1 : 0;
3802
	if (!double_answer) {
3811
	if (!double_answer) {
3803
		/* this still can result in double answer if the channel context
3812
		/* this still can result in double answer if the channel context
3804
		* was configured that way */
3813
		* was configured that way */
3805
		res = openr2_chan_answer_call(p->r2chan);
3814
		res = openr2_chan_answer_call(p->r2chan);
3806
	} else if (wants_double_answer) {
3815
	} else if (wants_double_answer) {
3807
		res = openr2_chan_answer_call_with_mode(p->r2chan, OR2_ANSWER_DOUBLE);
3816
		res = openr2_chan_answer_call_with_mode(p->r2chan, OR2_ANSWER_DOUBLE);
3808
	} else {
3817
	} else {
3809
		res = openr2_chan_answer_call_with_mode(p->r2chan, OR2_ANSWER_SIMPLE);
3818
		res = openr2_chan_answer_call_with_mode(p->r2chan, OR2_ANSWER_SIMPLE);
3810
	}
3819
	}
3811
#else
3820
#else
3812
	res = openr2_chan_answer_call(p->r2chan);
3821
	res = openr2_chan_answer_call(p->r2chan);
3813
#endif
3822
#endif
3814
	return res;
3823
	return res;
3815
}
3824
}
3816

    
   
3825

   
3817

    
   
3826

   
3818

    
   
3827

   
3819
/* should be called with the ast_channel locked */
3828
/* should be called with the ast_channel locked */
3820
static openr2_calling_party_category_t dahdi_r2_get_channel_category(struct ast_channel *c)
3829
static openr2_calling_party_category_t dahdi_r2_get_channel_category(struct ast_channel *c)
3821
{
3830
{
3822
	openr2_calling_party_category_t cat;
3831
	openr2_calling_party_category_t cat;
3823
	const char *catstr = pbx_builtin_getvar_helper(c, "MFCR2_CATEGORY");
3832
	const char *catstr = pbx_builtin_getvar_helper(c, "MFCR2_CATEGORY");
3824
	struct dahdi_pvt *p = c->tech_pvt;
3833
	struct dahdi_pvt *p = c->tech_pvt;
3825
	if (ast_strlen_zero(catstr)) {
3834
	if (ast_strlen_zero(catstr)) {
3826
		ast_debug(1, "No MFC/R2 category specified for chan %s, using default %s\n",
3835
		ast_debug(1, "No MFC/R2 category specified for chan %s, using default %s\n",
3827
				ast_channel_name(c), openr2_proto_get_category_string(p->mfcr2_category));
3836
				ast_channel_name(c), openr2_proto_get_category_string(p->mfcr2_category));
3828
		return p->mfcr2_category;
3837
		return p->mfcr2_category;
3829
	}
3838
	}
3830
	if ((cat = openr2_proto_get_category(catstr)) == OR2_CALLING_PARTY_CATEGORY_UNKNOWN) {
3839
	if ((cat = openr2_proto_get_category(catstr)) == OR2_CALLING_PARTY_CATEGORY_UNKNOWN) {
3831
		ast_log(LOG_WARNING, "Invalid category specified '%s' for chan %s, using default %s\n",
3840
		ast_log(LOG_WARNING, "Invalid category specified '%s' for chan %s, using default %s\n",
3832
				catstr, ast_channel_name(c), openr2_proto_get_category_string(p->mfcr2_category));
3841
				catstr, ast_channel_name(c), openr2_proto_get_category_string(p->mfcr2_category));
3833
		return p->mfcr2_category;
3842
		return p->mfcr2_category;
3834
	}
3843
	}
3835
	ast_debug(1, "Using category %s\n", catstr);
3844
	ast_debug(1, "Using category %s\n", catstr);
3836
	return cat;
3845
	return cat;
3837
}
3846
}
3838

    
   
3847

   
3839
static void dahdi_r2_on_call_init(openr2_chan_t *r2chan)
3848
static void dahdi_r2_on_call_init(openr2_chan_t *r2chan)
3840
{
3849
{
3841
	struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
3850
	struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
3842
	ast_mutex_lock(&p->lock);
3851
	ast_mutex_lock(&p->lock);
3843
	if (p->mfcr2call) {
3852
	if (p->mfcr2call) {
3844
		ast_mutex_unlock(&p->lock);
3853
		ast_mutex_unlock(&p->lock);
3845
		/* TODO: This can happen when some other thread just finished dahdi_request requesting this very same
3854
		/* TODO: This can happen when some other thread just finished dahdi_request requesting this very same
3846
		   interface but has not yet seized the line (dahdi_call), and the far end wins and seize the line,
3855
		   interface but has not yet seized the line (dahdi_call), and the far end wins and seize the line,
3847
		   can we avoid this somehow?, at this point when dahdi_call send the seize, it is likely that since
3856
		   can we avoid this somehow?, at this point when dahdi_call send the seize, it is likely that since
3848
		   the other end will see our seize as a forced release and drop the call, we will see an invalid
3857
		   the other end will see our seize as a forced release and drop the call, we will see an invalid
3849
		   pattern that will be seen and treated as protocol error. */
3858
		   pattern that will be seen and treated as protocol error. */
3850
		ast_log(LOG_ERROR, "Collision of calls on chan %d detected!.\n", openr2_chan_get_number(r2chan));
3859
		ast_log(LOG_ERROR, "Collision of calls on chan %d detected!.\n", openr2_chan_get_number(r2chan));
3851
		return;
3860
		return;
3852
	}
3861
	}
3853
	p->mfcr2call = 1;
3862
	p->mfcr2call = 1;
3854
	/* better safe than sorry ... */
3863
	/* better safe than sorry ... */
3855
	p->cid_name[0] = '\0';
3864
	p->cid_name[0] = '\0';
3856
	p->cid_num[0] = '\0';
3865
	p->cid_num[0] = '\0';
3857
	p->cid_subaddr[0] = '\0';
3866
	p->cid_subaddr[0] = '\0';
3858
	p->rdnis[0] = '\0';
3867
	p->rdnis[0] = '\0';
3859
	p->exten[0] = '\0';
3868
	p->exten[0] = '\0';
3860
	p->mfcr2_ani_index = '\0';
3869
	p->mfcr2_ani_index = '\0';
3861
	p->mfcr2_dnis_index = '\0';
3870
	p->mfcr2_dnis_index = '\0';
3862
	p->mfcr2_dnis_matched = 0;
3871
	p->mfcr2_dnis_matched = 0;
3863
	p->mfcr2_answer_pending = 0;
3872
	p->mfcr2_answer_pending = 0;
3864
	p->mfcr2_call_accepted = 0;
3873
	p->mfcr2_call_accepted = 0;
3865
	ast_mutex_unlock(&p->lock);
3874
	ast_mutex_unlock(&p->lock);
3866
	ast_verbose("New MFC/R2 call detected on chan %d.\n", openr2_chan_get_number(r2chan));
3875
	ast_verbose("New MFC/R2 call detected on chan %d.\n", openr2_chan_get_number(r2chan));
3867
}
3876
}
3868

    
   
3877

   
3869
static void dahdi_r2_on_hardware_alarm(openr2_chan_t *r2chan, int alarm)
3878
static void dahdi_r2_on_hardware_alarm(openr2_chan_t *r2chan, int alarm)
3870
{
3879
{
3871
	int res;
3880
	int res;
3872
	struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
3881
	struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
3873
	ast_mutex_lock(&p->lock);
3882
	ast_mutex_lock(&p->lock);
3874
	p->inalarm = alarm ? 1 : 0;
3883
	p->inalarm = alarm ? 1 : 0;
3875
	if (p->inalarm) {
3884
	if (p->inalarm) {
3876
		res = get_alarms(p);
3885
		res = get_alarms(p);
3877
		handle_alarms(p, res);
3886
		handle_alarms(p, res);
3878
	} else {
3887
	} else {
3879
		handle_clear_alarms(p);
3888
		handle_clear_alarms(p);
3880
	}
3889
	}
3881
	ast_mutex_unlock(&p->lock);
3890
	ast_mutex_unlock(&p->lock);
3882
}
3891
}
3883

    
   
3892

   
3884
static void dahdi_r2_on_os_error(openr2_chan_t *r2chan, int errorcode)
3893
static void dahdi_r2_on_os_error(openr2_chan_t *r2chan, int errorcode)
3885
{
3894
{
3886
	ast_log(LOG_ERROR, "OS error on chan %d: %s\n", openr2_chan_get_number(r2chan), strerror(errorcode));
3895
	ast_log(LOG_ERROR, "OS error on chan %d: %s\n", openr2_chan_get_number(r2chan), strerror(errorcode));
3887
}
3896
}
3888

    
   
3897

   
3889
static void dahdi_r2_on_protocol_error(openr2_chan_t *r2chan, openr2_protocol_error_t reason)
3898
static void dahdi_r2_on_protocol_error(openr2_chan_t *r2chan, openr2_protocol_error_t reason)
3890
{
3899
{
3891
	struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
3900
	struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
3892
	ast_log(LOG_ERROR, "MFC/R2 protocol error on chan %d: %s\n", openr2_chan_get_number(r2chan), openr2_proto_get_error(reason));
3901
	ast_log(LOG_ERROR, "MFC/R2 protocol error on chan %d: %s\n", openr2_chan_get_number(r2chan), openr2_proto_get_error(reason));
3893
	if (p->owner) {
3902
	if (p->owner) {
3894
		p->owner->hangupcause = AST_CAUSE_PROTOCOL_ERROR;
3903
		p->owner->hangupcause = AST_CAUSE_PROTOCOL_ERROR;
3895
		p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
3904
		p->owner->_softhangup |= AST_SOFTHANGUP_DEV;
3896
	}
3905
	}
3897
	ast_mutex_lock(&p->lock);
3906
	ast_mutex_lock(&p->lock);
3898
	p->mfcr2call = 0;
3907
	p->mfcr2call = 0;
3899
	ast_mutex_unlock(&p->lock);
3908
	ast_mutex_unlock(&p->lock);
3900
}
3909
}
3901

    
   
3910

   
3902
static void dahdi_r2_disconnect_call(struct dahdi_pvt *p, openr2_call_disconnect_cause_t cause)
3911
static void dahdi_r2_disconnect_call(struct dahdi_pvt *p, openr2_call_disconnect_cause_t cause)
3903
{
3912
{
3904
	if (openr2_chan_disconnect_call(p->r2chan, cause)) {
3913
	if (openr2_chan_disconnect_call(p->r2chan, cause)) {
3905
		ast_log(LOG_NOTICE, "Bad! failed to disconnect call on channel %d with reason %s, hope for the best!\n",
3914
		ast_log(LOG_NOTICE, "Bad! failed to disconnect call on channel %d with reason %s, hope for the best!\n",
3906
		   p->channel, openr2_proto_get_disconnect_string(cause));
3915
		   p->channel, openr2_proto_get_disconnect_string(cause));
3907
		/* force the chan to idle and release the call flag now since we will not see a clean on_call_end */
3916
		/* force the chan to idle and release the call flag now since we will not see a clean on_call_end */
3908
		openr2_chan_set_idle(p->r2chan);
3917
		openr2_chan_set_idle(p->r2chan);
3909
		ast_mutex_lock(&p->lock);
3918
		ast_mutex_lock(&p->lock);
3910
		p->mfcr2call = 0;
3919
		p->mfcr2call = 0;
3911
		ast_mutex_unlock(&p->lock);
3920
		ast_mutex_unlock(&p->lock);
3912
	}
3921
	}
3913
}
3922
}
3914

    
   
3923

   
3915
static void dahdi_r2_on_call_offered(openr2_chan_t *r2chan, const char *ani, const char *dnis, openr2_calling_party_category_t category)
3924
static void dahdi_r2_on_call_offered(openr2_chan_t *r2chan, const char *ani, const char *dnis, openr2_calling_party_category_t category)
3916
{
3925
{
3917
	struct dahdi_pvt *p;
3926
	struct dahdi_pvt *p;
3918
	struct ast_channel *c;
3927
	struct ast_channel *c;
3919
	ast_verbose("MFC/R2 call offered on chan %d. ANI = %s, DNIS = %s, Category = %s\n",
3928
	ast_verbose("MFC/R2 call offered on chan %d. ANI = %s, DNIS = %s, Category = %s\n",
3920
			openr2_chan_get_number(r2chan), ani ? ani : "(restricted)", dnis,
3929
			openr2_chan_get_number(r2chan), ani ? ani : "(restricted)", dnis,
3921
			openr2_proto_get_category_string(category));
3930
			openr2_proto_get_category_string(category));
3922
	p = openr2_chan_get_client_data(r2chan);
3931
	p = openr2_chan_get_client_data(r2chan);
3923
	/* if collect calls are not allowed and this is a collect call, reject it! */
3932
	/* if collect calls are not allowed and this is a collect call, reject it! */
3924
	if (!p->mfcr2_allow_collect_calls && category == OR2_CALLING_PARTY_CATEGORY_COLLECT_CALL) {
3933
	if (!p->mfcr2_allow_collect_calls && category == OR2_CALLING_PARTY_CATEGORY_COLLECT_CALL) {
3925
		ast_log(LOG_NOTICE, "Rejecting MFC/R2 collect call\n");
3934
		ast_log(LOG_NOTICE, "Rejecting MFC/R2 collect call\n");
3926
		dahdi_r2_disconnect_call(p, OR2_CAUSE_COLLECT_CALL_REJECTED);
3935
		dahdi_r2_disconnect_call(p, OR2_CAUSE_COLLECT_CALL_REJECTED);
3927
		return;
3936
		return;
3928
	}
3937
	}
3929
	ast_mutex_lock(&p->lock);
3938
	ast_mutex_lock(&p->lock);
3930
	p->mfcr2_recvd_category = category;
3939
	p->mfcr2_recvd_category = category;
3931
	/* if we're not supposed to use CID, clear whatever we have */
3940
	/* if we're not supposed to use CID, clear whatever we have */
3932
	if (!p->use_callerid) {
3941
	if (!p->use_callerid) {
3933
		ast_debug(1, "No CID allowed in configuration, CID is being cleared!\n");
3942
		ast_debug(1, "No CID allowed in configuration, CID is being cleared!\n");
3934
		p->cid_num[0] = 0;
3943
		p->cid_num[0] = 0;
3935
		p->cid_name[0] = 0;
3944
		p->cid_name[0] = 0;
3936
	}
3945
	}
3937
	/* if we're supposed to answer immediately, clear DNIS and set 's' exten */
3946
	/* if we're supposed to answer immediately, clear DNIS and set 's' exten */
3938
	if (p->immediate || !openr2_context_get_max_dnis(openr2_chan_get_context(r2chan))) {
3947
	if (p->immediate || !openr2_context_get_max_dnis(openr2_chan_get_context(r2chan))) {
3939
		ast_debug(1, "Setting exten => s because of immediate or 0 DNIS configured\n");
3948
		ast_debug(1, "Setting exten => s because of immediate or 0 DNIS configured\n");
3940
		p->exten[0] = 's';
3949
		p->exten[0] = 's';
3941
		p->exten[1] = 0;
3950
		p->exten[1] = 0;
3942
	}
3951
	}
3943
	ast_mutex_unlock(&p->lock);
3952
	ast_mutex_unlock(&p->lock);
3944
	if (!ast_exists_extension(NULL, p->context, p->exten, 1, p->cid_num)) {
3953
	if (!ast_exists_extension(NULL, p->context, p->exten, 1, p->cid_num)) {
3945
		ast_log(LOG_NOTICE, "MFC/R2 call on channel %d requested non-existent extension '%s' in context '%s'. Rejecting call.\n",
3954
		ast_log(LOG_NOTICE, "MFC/R2 call on channel %d requested non-existent extension '%s' in context '%s'. Rejecting call.\n",
3946
				p->channel, p->exten, p->context);
3955
				p->channel, p->exten, p->context);
3947
		dahdi_r2_disconnect_call(p, OR2_CAUSE_UNALLOCATED_NUMBER);
3956
		dahdi_r2_disconnect_call(p, OR2_CAUSE_UNALLOCATED_NUMBER);
3948
		return;
3957
		return;
3949
	}
3958
	}
3950
	if (!p->mfcr2_accept_on_offer) {
3959
	if (!p->mfcr2_accept_on_offer) {
3951
		/* The user wants us to start the PBX thread right away without accepting the call first */
3960
		/* The user wants us to start the PBX thread right away without accepting the call first */
3952
		c = dahdi_new(p, AST_STATE_RING, 1, SUB_REAL, DAHDI_LAW_ALAW, NULL);
3961
		c = dahdi_new(p, AST_STATE_RING, 1, SUB_REAL, DAHDI_LAW_ALAW, NULL);
3953
		if (c) {
3962
		if (c) {
3954
			/* Done here, don't disable reading now since we still need to generate MF tones to accept
3963
			/* Done here, don't disable reading now since we still need to generate MF tones to accept
3955
			   the call or reject it and detect the tone off condition of the other end, all of this
3964
			   the call or reject it and detect the tone off condition of the other end, all of this
3956
			   will be done in the PBX thread now */
3965
			   will be done in the PBX thread now */
3957
			return;
3966
			return;
3958
		}
3967
		}
3959
		ast_log(LOG_WARNING, "Unable to create PBX channel in DAHDI channel %d\n", p->channel);
3968
		ast_log(LOG_WARNING, "Unable to create PBX channel in DAHDI channel %d\n", p->channel);
3960
		dahdi_r2_disconnect_call(p, OR2_CAUSE_OUT_OF_ORDER);
3969
		dahdi_r2_disconnect_call(p, OR2_CAUSE_OUT_OF_ORDER);
3961
	} else if (p->mfcr2_charge_calls) {
3970
	} else if (p->mfcr2_charge_calls) {
3962
		ast_debug(1, "Accepting MFC/R2 call with charge on chan %d\n", p->channel);
3971
		ast_debug(1, "Accepting MFC/R2 call with charge on chan %d\n", p->channel);
3963
		openr2_chan_accept_call(r2chan, OR2_CALL_WITH_CHARGE);
3972
		openr2_chan_accept_call(r2chan, OR2_CALL_WITH_CHARGE);
3964
	} else {
3973
	} else {
3965
		ast_debug(1, "Accepting MFC/R2 call with no charge on chan %d\n", p->channel);
3974
		ast_debug(1, "Accepting MFC/R2 call with no charge on chan %d\n", p->channel);
3966
		openr2_chan_accept_call(r2chan, OR2_CALL_NO_CHARGE);
3975
		openr2_chan_accept_call(r2chan, OR2_CALL_NO_CHARGE);
3967
	}
3976
	}
3968
}
3977
}
3969

    
   
3978

   
3970
static void dahdi_r2_on_call_end(openr2_chan_t *r2chan)
3979
static void dahdi_r2_on_call_end(openr2_chan_t *r2chan)
3971
{
3980
{
3972
	struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
3981
	struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
3973
	ast_verbose("MFC/R2 call end on channel %d\n", p->channel);
3982
	ast_verbose("MFC/R2 call end on channel %d\n", p->channel);
3974
	ast_mutex_lock(&p->lock);
3983
	ast_mutex_lock(&p->lock);
3975
	p->mfcr2call = 0;
3984
	p->mfcr2call = 0;
3976
	ast_mutex_unlock(&p->lock);
3985
	ast_mutex_unlock(&p->lock);
3977
}
3986
}
3978

    
   
3987

   
3979
static void dahdi_enable_ec(struct dahdi_pvt *p);
3988
static void dahdi_enable_ec(struct dahdi_pvt *p);
3980
static void dahdi_r2_on_call_accepted(openr2_chan_t *r2chan, openr2_call_mode_t mode)
3989
static void dahdi_r2_on_call_accepted(openr2_chan_t *r2chan, openr2_call_mode_t mode)
3981
{
3990
{
3982
	struct dahdi_pvt *p = NULL;
3991
	struct dahdi_pvt *p = NULL;
3983
	struct ast_channel *c = NULL;
3992
	struct ast_channel *c = NULL;
3984
	p = openr2_chan_get_client_data(r2chan);
3993
	p = openr2_chan_get_client_data(r2chan);
3985
	dahdi_enable_ec(p);
3994
	dahdi_enable_ec(p);
3986
	p->mfcr2_call_accepted = 1;
3995
	p->mfcr2_call_accepted = 1;
3987
	/* if it's an incoming call ... */
3996
	/* if it's an incoming call ... */
3988
	if (OR2_DIR_BACKWARD == openr2_chan_get_direction(r2chan)) {
3997
	if (OR2_DIR_BACKWARD == openr2_chan_get_direction(r2chan)) {
3989
		ast_verbose("MFC/R2 call has been accepted on backward channel %d\n", openr2_chan_get_number(r2chan));
3998
		ast_verbose("MFC/R2 call has been accepted on backward channel %d\n", openr2_chan_get_number(r2chan));
3990
		/* If accept on offer is not set, it means at this point the PBX thread is already
3999
		/* If accept on offer is not set, it means at this point the PBX thread is already
3991
		   launched (was launched in the 'on call offered' handler) and therefore this callback
4000
		   launched (was launched in the 'on call offered' handler) and therefore this callback
3992
		   is being executed already in the PBX thread rather than the monitor thread, don't launch
4001
		   is being executed already in the PBX thread rather than the monitor thread, don't launch
3993
		   any other thread, just disable the openr2 reading and answer the call if needed */
4002
		   any other thread, just disable the openr2 reading and answer the call if needed */
3994
		if (!p->mfcr2_accept_on_offer) {
4003
		if (!p->mfcr2_accept_on_offer) {
3995
			openr2_chan_disable_read(r2chan);
4004
			openr2_chan_disable_read(r2chan);
3996
			if (p->mfcr2_answer_pending) {
4005
			if (p->mfcr2_answer_pending) {
3997
				ast_debug(1, "Answering MFC/R2 call after accepting it on chan %d\n", openr2_chan_get_number(r2chan));
4006
				ast_debug(1, "Answering MFC/R2 call after accepting it on chan %d\n", openr2_chan_get_number(r2chan));
3998
				dahdi_r2_answer(p);
4007
				dahdi_r2_answer(p);
3999
			}
4008
			}
4000
			return;
4009
			return;
4001
		}
4010
		}
4002
		c = dahdi_new(p, AST_STATE_RING, 1, SUB_REAL, DAHDI_LAW_ALAW, NULL);
4011
		c = dahdi_new(p, AST_STATE_RING, 1, SUB_REAL, DAHDI_LAW_ALAW, NULL);
4003
		if (c) {
4012
		if (c) {
4004
			/* chan_dahdi will take care of reading from now on in the PBX thread, tell the
4013
			/* chan_dahdi will take care of reading from now on in the PBX thread, tell the
4005
			   library to forget about it */
4014
			   library to forget about it */
4006
			openr2_chan_disable_read(r2chan);
4015
			openr2_chan_disable_read(r2chan);
4007
			return;
4016
			return;
4008
		}
4017
		}
4009
		ast_log(LOG_WARNING, "Unable to create PBX channel in DAHDI channel %d\n", p->channel);
4018
		ast_log(LOG_WARNING, "Unable to create PBX channel in DAHDI channel %d\n", p->channel);
4010
		/* failed to create the channel, bail out and report it as an out of order line */
4019
		/* failed to create the channel, bail out and report it as an out of order line */
4011
		dahdi_r2_disconnect_call(p, OR2_CAUSE_OUT_OF_ORDER);
4020
		dahdi_r2_disconnect_call(p, OR2_CAUSE_OUT_OF_ORDER);
4012
		return;
4021
		return;
4013
	}
4022
	}
4014
	/* this is an outgoing call, no need to launch the PBX thread, most likely we're in one already */
4023
	/* this is an outgoing call, no need to launch the PBX thread, most likely we're in one already */
4015
	ast_verbose("MFC/R2 call has been accepted on forward channel %d\n", p->channel);
4024
	ast_verbose("MFC/R2 call has been accepted on forward channel %d\n", p->channel);
4016
	p->subs[SUB_REAL].needringing = 1;
4025
	p->subs[SUB_REAL].needringing = 1;
4017
	p->dialing = 0;
4026
	p->dialing = 0;
4018
	/* chan_dahdi will take care of reading from now on in the PBX thread, tell the library to forget about it */
4027
	/* chan_dahdi will take care of reading from now on in the PBX thread, tell the library to forget about it */
4019
	openr2_chan_disable_read(r2chan);
4028
	openr2_chan_disable_read(r2chan);
4020
}
4029
}
4021

    
   
4030

   
4022
static void dahdi_r2_on_call_answered(openr2_chan_t *r2chan)
4031
static void dahdi_r2_on_call_answered(openr2_chan_t *r2chan)
4023
{
4032
{
4024
	struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
4033
	struct dahdi_pvt *p = openr2_chan_get_client_data(r2chan);
4025
	ast_verbose("MFC/R2 call has been answered on channel %d\n", openr2_chan_get_number(r2chan));
4034
	ast_verbose("MFC/R2 call has been answered on channel %d\n", openr2_chan_get_number(r2chan));
4026
	p->subs[SUB_REAL].needanswer = 1;
4035
	p->subs[SUB_REAL].needanswer = 1;