~ubuntu-branches/debian/squeeze/asterisk-chan-capi/squeeze

« back to all changes in this revision

Viewing changes to chan_capi.c

  • Committer: Bazaar Package Importer
  • Author(s): Ben Hutchings
  • Date: 2007-03-07 01:58:53 UTC
  • mfrom: (3.1.3 feisty)
  • Revision ID: james.westby@ubuntu.com-20070307015853-yw0ov095k4fx2rza
Tags: 0.7.1-1.1
* Non-maintainer upload
* Protect calls to capi_cmsg2str and use of its buffer with a mutex.
  (Closes: #411293)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
 * (CAPI*)
3
3
 *
4
 
 * An implementation of Common ISDN API 2.0 for Asterisk
5
 
 *
6
 
 * Copyright (C) 2002, 2003, 2004, Junghanns.NET GmbH
 
4
 * An implementation of Common ISDN API 2.0 for
 
5
 * Asterisk / OpenPBX.org
 
6
 *
 
7
 * Copyright (C) 2005-2006 Cytronics & Melware
 
8
 *
 
9
 * Armin Schindler <armin@melware.de>
 
10
 * 
 
11
 * Reworked, but based on the work of
 
12
 * Copyright (C) 2002-2005 Junghanns.NET GmbH
7
13
 *
8
14
 * Klaus-Peter Junghanns <kapejod@ns1.jnetdns.de>
9
15
 *
10
16
 * This program is free software and may be modified and 
11
17
 * distributed under the terms of the GNU Public License.
12
18
 */
 
19
#ifdef PBX_IS_OPBX
 
20
#ifdef HAVE_CONFIG_H
 
21
#include "confdefs.h"
 
22
#endif
 
23
#endif
 
24
 
 
25
#include <sys/time.h>
 
26
#include <sys/signal.h>
 
27
#include <stdlib.h>
 
28
#include <stdio.h>
 
29
#include <string.h>
 
30
#include <ctype.h>
 
31
#include <errno.h>
 
32
#include <unistd.h>
 
33
#include <fcntl.h>
 
34
#include <sys/types.h>
 
35
 
 
36
#ifdef PBX_IS_OPBX
 
37
#include "openpbx.h"
 
38
 
 
39
OPENPBX_FILE_VERSION("$HeadURL$", "$Revision: 392 $")
 
40
 
 
41
#include "openpbx/lock.h"
 
42
#include "openpbx/frame.h" 
 
43
#include "openpbx/channel.h"
 
44
#include "openpbx/logger.h"
 
45
#include "openpbx/module.h"
 
46
#include "openpbx/pbx.h"
 
47
#include "openpbx/config.h"
 
48
#include "openpbx/options.h"
 
49
#include "openpbx/features.h"
 
50
#include "openpbx/utils.h"
 
51
#include "openpbx/cli.h"
 
52
#include "openpbx/rtp.h"
 
53
#include "openpbx/causes.h"
 
54
#include "openpbx/strings.h"
 
55
#include "openpbx/devicestate.h"
 
56
#include "openpbx/dsp.h"
 
57
#include "openpbx/xlaw.h"
 
58
#include "openpbx/chan_capi20.h"
 
59
#include "openpbx/chan_capi.h"
 
60
#include "openpbx/chan_capi_rtp.h"
 
61
#else
 
62
#include "config.h"
13
63
 
14
64
#include <asterisk/lock.h>
15
65
#include <asterisk/frame.h> 
16
66
#include <asterisk/channel.h>
17
 
#include <asterisk/channel_pvt.h>
18
67
#include <asterisk/logger.h>
19
68
#include <asterisk/module.h>
20
69
#include <asterisk/pbx.h>
23
72
#include <asterisk/features.h>
24
73
#include <asterisk/utils.h>
25
74
#include <asterisk/cli.h>
26
 
#include <sys/time.h>
27
 
#include <sys/signal.h>
28
 
#include <stdlib.h>
29
 
#include <stdio.h>
30
 
#include <string.h>
31
 
#include <errno.h>
32
 
#include <unistd.h>
33
 
#include <fcntl.h>
34
 
#include <sys/types.h>
35
 
#include <linux/capi.h>
36
 
#include <capi20.h>
 
75
#include <asterisk/rtp.h>
 
76
#include <asterisk/causes.h>
 
77
#include <asterisk/strings.h>
37
78
#include <asterisk/dsp.h>
 
79
#include <asterisk/devicestate.h>
38
80
#include "xlaw.h"
39
 
#include "chan_capi_pvt.h"
40
 
 
41
 
unsigned ast_capi_ApplID;
42
 
_cword ast_capi_MessageNumber=1;
43
 
static char *desc = "Common ISDN API for Asterisk";
44
 
#ifdef CAPI_ULAW
45
 
#ifdef UNSTABLE_CVS
46
 
static char *tdesc = "Common ISDN API Driver (0.3.5) muLaw CVS HEAD";
47
 
#else
48
 
static char *tdesc = "Common ISDN API Driver (0.3.5) muLaw";
49
 
#endif
50
 
#else
51
 
#ifdef UNSTABLE_CVS
52
 
static char *tdesc = "Common ISDN API Driver (0.3.5) aLaw CVS HEAD";
53
 
#else
54
 
static char *tdesc = "Common ISDN API Driver (0.3.5) aLaw";
55
 
#endif
56
 
#endif
57
 
static char *type = "CAPI";
58
 
 
 
81
#include "chan_capi20.h"
 
82
#include "chan_capi.h"
 
83
#include "chan_capi_rtp.h"
 
84
#endif
 
85
 
 
86
#ifdef PBX_IS_OPBX
 
87
#define CC_VERSION "cm-opbx-0.7"
 
88
#else
 
89
#define CC_VERSION "0.7.1"
 
90
/* #define CC_VERSION "$Revision: 392 $" */
 
91
#endif
 
92
 
 
93
/*
 
94
 * personal stuff
 
95
 */
 
96
#undef   CAPI_APPLID_UNUSED
 
97
#define  CAPI_APPLID_UNUSED 0xffffffff
 
98
unsigned capi_ApplID = CAPI_APPLID_UNUSED;
 
99
 
 
100
static _cword capi_MessageNumber;
 
101
#ifdef PBX_IS_OPBX
 
102
static char *ccdesc = "Common ISDN API for OpenPBX";
 
103
#else
 
104
static char *ccdesc = "Common ISDN API for Asterisk";
 
105
#endif
 
106
static const char tdesc[] = "Common ISDN API Driver (" CC_VERSION ")";
 
107
static const char channeltype[] = "CAPI";
 
108
static const struct ast_channel_tech capi_tech;
 
109
 
 
110
static char *commandtdesc = "CAPI command interface.\n"
 
111
"The dial command:\n"
 
112
"Dial(CAPI/g<group>/[<callerid>:]<destination>[/<params>])\n"
 
113
"Dial(CAPI/contr<controller>/[<callerid>:]<destination>[/<params>])\n"
 
114
"Dial(CAPI/<interface-name>/[<callerid>:]<destination>[/<params>])\n"
 
115
"\"params\" can be:\n"
 
116
"early B3:\"b\"=always, \"B\"=on successful calls only\n"
 
117
"\"d\":use callerID from capi.conf, \"o\":overlap sending number\n"
 
118
"\n"
 
119
"capicommand() where () can be:\n"
 
120
"\"deflect|to_number\" forwards an unanswered call to number\n"
 
121
"\"malicous\" report a call of malicious nature\n"
 
122
"\"echocancel|<yes> or <no>\" echo-cancel provided by driver/hardware\n"
 
123
"\"echosquelch|<yes> or <no>\" very primitive echo-squelch by chan-capi\n"
 
124
"\"holdtype|<local> or <hold>\" set type of 'hold'\n"
 
125
"\"hold[|MYHOLDVAR]\" puts an answered call on hold\n"
 
126
"\"retrieve|${MYHOLDVAR}\" gets back the held call\n"
 
127
"\"ect|${MYHOLDVAR})\" explicit call transfer of call on hold\n"
 
128
"\"receivefax|filename|stationID|headline\" receive a CAPIfax\n"
 
129
"\"sendfax|filename.sff|stationID|headline\" send a CAPIfax\n"
 
130
"Variables set after fax receive:\n"
 
131
"FAXSTATUS     :0=OK, 1=Error\n"
 
132
"FAXREASON     :B3 disconnect reason\n"
 
133
"FAXREASONTEXT :FAXREASON as text\n"
 
134
"FAXRATE       :baud rate of fax connection\n"
 
135
"FAXRESOLUTION :0=standard, 1=high\n"
 
136
"FAXFORMAT     :0=SFF\n"
 
137
"FAXPAGES      :Number of pages received\n"
 
138
"FAXID         :ID of the remote fax machine\n"
 
139
"Asterisk variables used/set by chan_capi:\n"
 
140
"BCHANNELINFO,CALLEDTON,_CALLERHOLDID,CALLINGSUBADDRESS,CALLEDSUBADDRESS\n"
 
141
"CONNECTEDNUMBER,FAXEXTEN,PRI_CAUSE,REDIRECTINGNUMBER,REDIRECTREASON\n"
 
142
"!!! for more details and samples, check the README of chan-capi !!!\n";
 
143
 
 
144
static char *commandapp = "capiCommand";
 
145
static char *commandsynopsis = "Execute special CAPI commands";
 
146
STANDARD_LOCAL_USER;
 
147
LOCAL_USER_DECL;
59
148
 
60
149
static int usecnt;
61
 
#ifdef UNSTABLE_CVS
 
150
 
 
151
/*
 
152
 * LOCKING RULES
 
153
 * =============
 
154
 *
 
155
 * This channel driver uses several locks. One must be 
 
156
 * careful not to reverse the locking order, which will
 
157
 * lead to a so called deadlock. Here is the locking order
 
158
 * that must be followed:
 
159
 *
 
160
 * struct capi_pvt *i;
 
161
 *
 
162
 * 1. cc_mutex_lock(&i->owner->lock); **
 
163
 *
 
164
 * 2. cc_mutex_lock(&i->lock);
 
165
 *
 
166
 * 3. cc_mutex_lock(&iflock);
 
167
 * 4. cc_mutex_lock(&messagenumber_lock);
 
168
 * 5. cc_mutex_lock(&usecnt_lock);
 
169
 * 6. cc_mutex_lock(&capi_put_lock);
 
170
 *
 
171
 *
 
172
 *  ** the PBX will call the callback functions with 
 
173
 *     this lock locked. This lock protects the 
 
174
 *     structure pointed to by 'i->owner'. Also note
 
175
 *     that calling some PBX functions will lock
 
176
 *     this lock!
 
177
 */
 
178
 
 
179
AST_MUTEX_DEFINE_STATIC(messagenumber_lock);
62
180
AST_MUTEX_DEFINE_STATIC(usecnt_lock);
63
181
AST_MUTEX_DEFINE_STATIC(iflock);
64
 
AST_MUTEX_DEFINE_STATIC(pipelock);
65
 
AST_MUTEX_DEFINE_STATIC(monlock);
66
 
AST_MUTEX_DEFINE_STATIC(contrlock);
67
 
AST_MUTEX_DEFINE_STATIC(capi_send_buffer_lock);
68
182
AST_MUTEX_DEFINE_STATIC(capi_put_lock);
69
 
#else
70
 
static ast_mutex_t usecnt_lock = AST_MUTEX_INITIALIZER;
71
 
static ast_mutex_t iflock = AST_MUTEX_INITIALIZER;
72
 
static ast_mutex_t pipelock = AST_MUTEX_INITIALIZER;
73
 
static ast_mutex_t monlock = AST_MUTEX_INITIALIZER;
74
 
static ast_mutex_t contrlock = AST_MUTEX_INITIALIZER;
75
 
static ast_mutex_t capi_send_buffer_lock = AST_MUTEX_INITIALIZER;
76
 
static ast_mutex_t capi_put_lock = AST_MUTEX_INITIALIZER;
77
 
#endif
 
183
AST_MUTEX_DEFINE_STATIC(verbose_lock);
78
184
 
79
 
#ifdef CAPI_ULAW
80
 
static int capi_capability = AST_FORMAT_ULAW;
81
 
#else
82
185
static int capi_capability = AST_FORMAT_ALAW;
83
 
#endif
84
 
static struct ast_capi_profile profile;
85
 
 
86
 
static pthread_t monitor_thread = -1;
87
 
 
88
 
static struct ast_capi_pvt *iflist = NULL;
89
 
static struct capi_pipe *pipelist = NULL;
90
 
static int capi_last_plci = 0;
91
 
static struct ast_capi_controller *capi_controllers[AST_CAPI_MAX_CONTROLLERS];
 
186
 
 
187
static pthread_t monitor_thread = (pthread_t)(0-1);
 
188
 
 
189
static struct capi_pvt *iflist = NULL;
 
190
static struct cc_capi_controller *capi_controllers[CAPI_MAX_CONTROLLERS + 1];
92
191
static int capi_num_controllers = 0;
93
 
static int capi_counter = 0;
94
 
static unsigned long capi_used_controllers=0;
95
 
 
96
 
static char capi_send_buffer[AST_CAPI_MAX_B3_BLOCKS * AST_CAPI_MAX_B3_BLOCK_SIZE];
97
 
static int capi_send_buffer_handle = 0;
98
 
 
99
 
char capi_national_prefix[AST_MAX_EXTENSION];
100
 
char capi_international_prefix[AST_MAX_EXTENSION];
101
 
 
102
 
int capidebug = 0;
103
 
 
104
 
MESSAGE_EXCHANGE_ERROR _capi_put_cmsg(_cmsg *CMSG) {
105
 
    MESSAGE_EXCHANGE_ERROR error;
106
 
    if (ast_mutex_lock(&capi_put_lock)) {
107
 
        ast_log(LOG_WARNING,"Unable to lock capi put!\n");
108
 
        return -1;
109
 
    } 
110
 
    error = capi20_put_cmsg(CMSG);    
111
 
    if (ast_mutex_unlock(&capi_put_lock)) {
112
 
        ast_log(LOG_WARNING,"Unable to unlock capi put!\n");
113
 
        return -1;
114
 
    }
115
 
    return error;
116
 
}
117
 
 
118
 
 
119
 
MESSAGE_EXCHANGE_ERROR check_wait_get_cmsg(_cmsg *CMSG) {
120
 
    MESSAGE_EXCHANGE_ERROR Info;
121
 
    struct timeval tv;
122
 
    tv.tv_sec = 0;
123
 
    tv.tv_usec = 10000;
124
 
    Info = capi20_waitformessage(ast_capi_ApplID,&tv);
125
 
    if ((Info != 0x0000) && (Info != 0x1104)) {
126
 
        printf("Error waiting for cmsg... INFO = %#x\n", Info);
 
192
static unsigned int capi_counter = 0;
 
193
static unsigned long capi_used_controllers = 0;
 
194
static char *emptyid = "\0";
 
195
 
 
196
static struct ast_channel *chan_for_task;
 
197
static int channel_task;
 
198
#define CAPI_CHANNEL_TASK_NONE             0
 
199
#define CAPI_CHANNEL_TASK_HANGUP           1
 
200
#define CAPI_CHANNEL_TASK_SOFTHANGUP       2
 
201
#define CAPI_CHANNEL_TASK_PICKUP           3
 
202
 
 
203
static char capi_national_prefix[AST_MAX_EXTENSION];
 
204
static char capi_international_prefix[AST_MAX_EXTENSION];
 
205
 
 
206
static char default_language[MAX_LANGUAGE] = "";
 
207
 
 
208
static int capidebug = 0;
 
209
 
 
210
/* local prototypes */
 
211
#ifdef CC_AST_HAS_INDICATE_DATA
 
212
static int pbx_capi_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
 
213
#else
 
214
static int pbx_capi_indicate(struct ast_channel *c, int condition);
 
215
#endif
 
216
 
 
217
/* external prototypes */
 
218
extern char *capi_info_string(unsigned int info);
 
219
 
 
220
/* */
 
221
#define return_on_no_interface(x)                                       \
 
222
        if (!i) {                                                       \
 
223
                cc_verbose(4, 1, "CAPI: %s no interface for PLCI=%#x\n", x, PLCI);   \
 
224
                return;                                                 \
 
225
        }
 
226
 
 
227
/*
 
228
 * helper for <pbx>_verbose with different verbose settings
 
229
 */
 
230
void cc_verbose(int o_v, int c_d, char *text, ...)
 
231
{
 
232
        char line[4096];
 
233
        va_list ap;
 
234
 
 
235
        va_start(ap, text);
 
236
        vsnprintf(line, sizeof(line), text, ap);
 
237
        va_end(ap);
 
238
 
 
239
        if ((o_v == 0) || (option_verbose > o_v)) {
 
240
                if ((!c_d) || ((c_d) && (capidebug))) { 
 
241
                        cc_mutex_lock(&verbose_lock);
 
242
                        cc_pbx_verbose(line);
 
243
                        cc_mutex_unlock(&verbose_lock); 
 
244
                }
 
245
        }
 
246
}
 
247
 
 
248
/*
 
249
 * B protocol settings
 
250
 */
 
251
static struct {
 
252
        _cword b1protocol;
 
253
        _cword b2protocol;
 
254
        _cword b3protocol;
 
255
        _cstruct b1configuration;
 
256
        _cstruct b2configuration;
 
257
        _cstruct b3configuration;
 
258
} b_protocol_table[] =
 
259
{
 
260
        { 0x01, 0x01, 0x00,     /* 0 */
 
261
                NULL,
 
262
                NULL,
 
263
                NULL
 
264
        },
 
265
        { 0x04, 0x04, 0x04,     /* 1 */
 
266
                NULL,
 
267
                NULL,
 
268
                NULL
 
269
        },
 
270
        { 0x1f, 0x1f, 0x1f,     /* 2 */
 
271
                (_cstruct) "\x00",
 
272
                /* (_cstruct) "\x04\x01\x00\x00\x02", */
 
273
                (_cstruct) "\x06\x01\x00\x58\x02\x32\x00",
 
274
                (_cstruct) "\x00"
 
275
        }
 
276
};
 
277
 
 
278
#ifndef CC_HAVE_NO_GLOBALCONFIGURATION
 
279
/*
 
280
 * set the global-configuration (b-channel operation)
 
281
 */
 
282
static _cstruct capi_set_global_configuration(struct capi_pvt *i)
 
283
{
 
284
        unsigned short dtedce = 0;
 
285
        unsigned char *buf = i->tmpbuf;
 
286
 
 
287
        buf[0] = 2; /* len */
 
288
 
 
289
        if (i->FaxState & CAPI_FAX_STATE_ACTIVE) {
 
290
                if ((i->outgoing) && (!(i->FaxState & CAPI_FAX_STATE_SENDMODE)))
 
291
                        dtedce = 2;
 
292
                if ((!(i->outgoing)) && ((i->FaxState & CAPI_FAX_STATE_SENDMODE)))
 
293
                        dtedce = 1;
 
294
        }
 
295
        write_capi_word(&buf[1], dtedce);
 
296
        if (dtedce == 0)
 
297
                buf = NULL;
 
298
        return (_cstruct)buf;
 
299
}
 
300
#endif
 
301
 
 
302
/*
 
303
 * command to string function
 
304
 */
 
305
static const char * capi_command_to_string(unsigned short wCmd)
 
306
{
 
307
        enum { lowest_value = CAPI_P_MIN,
 
308
               end_value = CAPI_P_MAX,
 
309
               range = end_value - lowest_value,
 
310
        };
 
311
 
 
312
#undef  CHAN_CAPI_COMMAND_DESC
 
313
#define CHAN_CAPI_COMMAND_DESC(n, ENUM, value)          \
 
314
        [CAPI_P_REQ(ENUM)-(n)]  = #ENUM "_REQ",         \
 
315
        [CAPI_P_CONF(ENUM)-(n)] = #ENUM "_CONF",        \
 
316
        [CAPI_P_IND(ENUM)-(n)]  = #ENUM "_IND",         \
 
317
        [CAPI_P_RESP(ENUM)-(n)] = #ENUM "_RESP",
 
318
 
 
319
        static const char * const table[range] = {
 
320
            CAPI_COMMANDS(CHAN_CAPI_COMMAND_DESC, lowest_value)
 
321
        };
 
322
 
 
323
        wCmd -= lowest_value;
 
324
 
 
325
        if (wCmd >= range) {
 
326
            goto error;
 
327
        }
 
328
 
 
329
        if (table[wCmd] == NULL) {
 
330
            goto error;
 
331
        }
 
332
        return table[wCmd];
 
333
 
 
334
 error:
 
335
        return "UNDEFINED";
 
336
}
 
337
 
 
338
/*
 
339
 * show the text for a CAPI message info value
 
340
 */
 
341
static void show_capi_info(struct capi_pvt *i, _cword info)
 
342
{
 
343
        char *p;
 
344
        char *name = "?";
 
345
        
 
346
        if (info == 0x0000) {
 
347
                /* no error, do nothing */
 
348
                return;
 
349
        }
 
350
 
 
351
        if (!(p = capi_info_string((unsigned int)info))) {
 
352
                /* message not available */
 
353
                return;
 
354
        }
 
355
 
 
356
        if (i)
 
357
                name = i->vname;
 
358
        
 
359
        cc_verbose(3, 0, VERBOSE_PREFIX_4 "%s: CAPI INFO 0x%04x: %s\n",
 
360
                name, info, p);
 
361
        return;
 
362
}
 
363
 
 
364
/*
 
365
 * get a new capi message number automically
 
366
 */
 
367
_cword get_capi_MessageNumber(void)
 
368
{
 
369
        _cword mn;
 
370
 
 
371
        cc_mutex_lock(&messagenumber_lock);
 
372
 
 
373
        capi_MessageNumber++;
 
374
        if (capi_MessageNumber == 0) {
 
375
            /* avoid zero */
 
376
            capi_MessageNumber = 1;
 
377
        }
 
378
 
 
379
        mn = capi_MessageNumber;
 
380
 
 
381
        cc_mutex_unlock(&messagenumber_lock);
 
382
 
 
383
        return(mn);
 
384
}
 
385
 
 
386
/*
 
387
 * write a capi message to capi device
 
388
 */
 
389
MESSAGE_EXCHANGE_ERROR _capi_put_cmsg(_cmsg *CMSG)
 
390
{
 
391
        MESSAGE_EXCHANGE_ERROR error;
 
392
        
 
393
        if (cc_mutex_lock(&capi_put_lock)) {
 
394
                cc_log(LOG_WARNING, "Unable to lock capi put!\n");
 
395
                return -1;
 
396
        } 
 
397
        
 
398
        error = capi20_put_cmsg(CMSG);
 
399
        
 
400
        if (cc_mutex_unlock(&capi_put_lock)) {
 
401
                cc_log(LOG_WARNING, "Unable to unlock capi put!\n");
 
402
                return -1;
 
403
        }
 
404
 
 
405
        if (error) {
 
406
                cc_log(LOG_ERROR, "CAPI error sending %s (NCCI=%#x) (error=%#x %s)\n",
 
407
                        capi_cmsg2str(CMSG), (unsigned int)HEADER_CID(CMSG),
 
408
                        error, capi_info_string((unsigned int)error));
 
409
        } else {
 
410
                unsigned short wCmd = HEADER_CMD(CMSG);
 
411
                if ((wCmd == CAPI_P_REQ(DATA_B3)) ||
 
412
                    (wCmd == CAPI_P_RESP(DATA_B3))) {
 
413
                        cc_verbose(7, 1, "%s\n", capi_cmsg2str(CMSG));
 
414
                } else {
 
415
                        cc_verbose(4, 1, "%s\n", capi_cmsg2str(CMSG));
 
416
                }
 
417
        }
 
418
 
 
419
        return error;
 
420
}
 
421
 
 
422
/*
 
423
 * wait for a specific message
 
424
 */
 
425
static MESSAGE_EXCHANGE_ERROR capi_wait_conf(struct capi_pvt *i, unsigned short wCmd)
 
426
{
 
427
        MESSAGE_EXCHANGE_ERROR error = 0;
 
428
        struct timespec abstime;
 
429
        unsigned char command, subcommand;
 
430
 
 
431
        subcommand = wCmd & 0xff;
 
432
        command = (wCmd & 0xff00) >> 8;
 
433
        i->waitevent = (unsigned int)wCmd;
 
434
        abstime.tv_sec = time(NULL) + 2;
 
435
        abstime.tv_nsec = 0;
 
436
        cc_verbose(4, 1, "%s: wait for %s (0x%x)\n",
 
437
                i->vname, capi_cmd2str(command, subcommand), i->waitevent);
 
438
        if (ast_cond_timedwait(&i->event_trigger, &i->lock, &abstime) != 0) {
 
439
                error = -1;
 
440
                cc_log(LOG_WARNING, "%s: timed out waiting for %s\n",
 
441
                        i->vname, capi_cmd2str(command, subcommand));
 
442
        } else {
 
443
                cc_verbose(4, 1, "%s: cond signal received for %s\n",
 
444
                        i->vname, capi_cmd2str(command, subcommand));
 
445
        }
 
446
        return error;
 
447
}
 
448
 
 
449
/*
 
450
 * write a capi message and wait for CONF
 
451
 * i->lock must be held
 
452
 */
 
453
MESSAGE_EXCHANGE_ERROR _capi_put_cmsg_wait_conf(struct capi_pvt *i, _cmsg *CMSG)
 
454
{
 
455
        MESSAGE_EXCHANGE_ERROR error;
 
456
 
 
457
        error = _capi_put_cmsg(CMSG);
 
458
 
 
459
        if (!(error)) {
 
460
                unsigned short wCmd = CAPICMD(CMSG->Command, CAPI_CONF);
 
461
                error = capi_wait_conf(i, wCmd);
 
462
        }
 
463
        return error;
 
464
}
 
465
 
 
466
/*
 
467
 * wait for B3 up
 
468
 */
 
469
static void capi_wait_for_b3_up(struct capi_pvt *i)
 
470
{
 
471
        struct timespec abstime;
 
472
 
 
473
        cc_mutex_lock(&i->lock);
 
474
        if (!(i->isdnstate & CAPI_ISDN_STATE_B3_UP)) {
 
475
                i->waitevent = CAPI_WAITEVENT_B3_UP;
 
476
                abstime.tv_sec = time(NULL) + 2;
 
477
                abstime.tv_nsec = 0;
 
478
                cc_verbose(4, 1, "%s: wait for b3 up.\n",
 
479
                        i->vname);
 
480
                if (ast_cond_timedwait(&i->event_trigger, &i->lock, &abstime) != 0) {
 
481
                        cc_log(LOG_WARNING, "%s: timed out waiting for b3 up.\n",
 
482
                                i->vname);
 
483
                } else {
 
484
                        cc_verbose(4, 1, "%s: cond signal received for b3 up.\n",
 
485
                                i->vname);
 
486
                }
 
487
        }
 
488
        cc_mutex_unlock(&i->lock);
 
489
}
 
490
 
 
491
/*
 
492
 * wait for finishing answering state
 
493
 */
 
494
static void capi_wait_for_answered(struct capi_pvt *i)
 
495
{
 
496
        struct timespec abstime;
 
497
 
 
498
        cc_mutex_lock(&i->lock);
 
499
        if (i->state == CAPI_STATE_ANSWERING) {
 
500
                i->waitevent = CAPI_WAITEVENT_ANSWER_FINISH;
 
501
                abstime.tv_sec = time(NULL) + 2;
 
502
                abstime.tv_nsec = 0;
 
503
                cc_verbose(4, 1, "%s: wait for finish answer.\n",
 
504
                        i->vname);
 
505
                if (ast_cond_timedwait(&i->event_trigger, &i->lock, &abstime) != 0) {
 
506
                        cc_log(LOG_WARNING, "%s: timed out waiting for finish answer.\n",
 
507
                                i->vname);
 
508
                } else {
 
509
                        cc_verbose(4, 1, "%s: cond signal received for finish answer.\n",
 
510
                                i->vname);
 
511
                }
 
512
        }
 
513
        cc_mutex_unlock(&i->lock);
 
514
}
 
515
 
 
516
/*
 
517
 * wait until fax activity has finished
 
518
 */
 
519
static void capi_wait_for_fax_finish(struct capi_pvt *i)
 
520
{
 
521
        struct timespec abstime;
 
522
        unsigned int timeout = 600; /* 10 minutes, to be sure */
 
523
 
 
524
        cc_mutex_lock(&i->lock);
 
525
        if (i->FaxState & CAPI_FAX_STATE_ACTIVE) {
 
526
                i->waitevent = CAPI_WAITEVENT_FAX_FINISH;
 
527
                abstime.tv_sec = time(NULL) + timeout;
 
528
                abstime.tv_nsec = 0;
 
529
                cc_verbose(4, 1, "%s: wait for finish fax (timeout %d seconds).\n",
 
530
                        i->vname, timeout);
 
531
                if (ast_cond_timedwait(&i->event_trigger, &i->lock, &abstime) != 0) {
 
532
                        cc_log(LOG_WARNING, "%s: timed out waiting for finish fax.\n",
 
533
                                i->vname);
 
534
                } else {
 
535
                        cc_verbose(4, 1, "%s: cond signal received for finish fax.\n",
 
536
                                i->vname);
 
537
                }
 
538
        }
 
539
        cc_mutex_unlock(&i->lock);
 
540
}
 
541
 
 
542
/*
 
543
 * wait some time for a new capi message
 
544
 */
 
545
static MESSAGE_EXCHANGE_ERROR capidev_check_wait_get_cmsg(_cmsg *CMSG)
 
546
{
 
547
        MESSAGE_EXCHANGE_ERROR Info;
 
548
        struct timeval tv;
 
549
 
 
550
 repeat:
 
551
        Info = capi_get_cmsg(CMSG, capi_ApplID);
 
552
 
 
553
#if (CAPI_OS_HINT == 1) || (CAPI_OS_HINT == 2)
 
554
        /*
 
555
         * For BSD allow controller 0:
 
556
         */
 
557
        if ((HEADER_CID(CMSG) & 0xFF) == 0) {
 
558
                HEADER_CID(CMSG) += capi_num_controllers;
 
559
        }
 
560
#endif
 
561
 
 
562
        /* if queue is empty */
 
563
        if (Info == 0x1104) {
 
564
                /* try waiting a maximum of 0.100 seconds for a message */
 
565
                tv.tv_sec = 0;
 
566
                tv.tv_usec = 10000;
 
567
                
 
568
                Info = capi20_waitformessage(capi_ApplID, &tv);
 
569
 
 
570
                if (Info == 0x0000)
 
571
                        goto repeat;
 
572
        }
 
573
        
 
574
        if ((Info != 0x0000) && (Info != 0x1104)) {
 
575
                if (capidebug) {
 
576
                        cc_log(LOG_DEBUG, "Error waiting for cmsg... INFO = %#x\n", Info);
 
577
                }
 
578
        }
 
579
    
127
580
        return Info;
128
 
    }
129
 
    
130
 
    if (Info == 0x0000) {
131
 
        Info = capi_get_cmsg(CMSG,ast_capi_ApplID);
132
 
    }
133
 
    return Info;
134
581
}
135
582
 
136
 
 
137
 
unsigned ListenOnController(unsigned long CIPmask,unsigned controller) {
138
 
    MESSAGE_EXCHANGE_ERROR  error;
139
 
    _cmsg                   CMSG,CMSG2;
140
 
 
141
 
    LISTEN_REQ_HEADER(&CMSG, ast_capi_ApplID, ast_capi_MessageNumber++, controller);
142
 
#ifdef NEVER_EVER_EARLY_B3_CONNECTS
143
 
    LISTEN_REQ_INFOMASK(&CMSG) = 0x00ff; // lots of info ;)
144
 
#else
145
 
    LISTEN_REQ_INFOMASK(&CMSG) = 0x03ff; // lots of info ;) + early B3 connect
146
 
#endif
147
 
    LISTEN_REQ_CIPMASK(&CMSG) = CIPmask;
148
 
    if ((error = _capi_put_cmsg(&CMSG)) != 0) {
 
583
/*
 
584
 * send Listen to specified controller
 
585
 */
 
586
static unsigned ListenOnController(unsigned long CIPmask, unsigned controller)
 
587
{
 
588
        MESSAGE_EXCHANGE_ERROR error;
 
589
        _cmsg CMSG;
 
590
        int waitcount = 100;
 
591
 
 
592
        LISTEN_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(), controller);
 
593
 
 
594
        LISTEN_REQ_INFOMASK(&CMSG) = 0xffff; /* lots of info ;) + early B3 connect */
 
595
                /* 0x00ff if no early B3 should be done */
 
596
                
 
597
        LISTEN_REQ_CIPMASK(&CMSG) = CIPmask;
 
598
        error = _capi_put_cmsg(&CMSG);
 
599
 
 
600
        if (error)
 
601
                goto done;
 
602
 
 
603
        while (waitcount) {
 
604
                error = capidev_check_wait_get_cmsg(&CMSG);
 
605
 
 
606
                if (IS_LISTEN_CONF(&CMSG)) {
 
607
                        error = LISTEN_CONF_INFO(&CMSG);
 
608
                        break;
 
609
                }
 
610
                usleep(20000);
 
611
                waitcount--;
 
612
        }
 
613
        if (!waitcount)
 
614
                error = 0x100F;
 
615
 
 
616
 done:
149
617
        return error;
150
 
    }
151
 
    while (!IS_LISTEN_CONF(&CMSG2)) {
152
 
        error = check_wait_get_cmsg(&CMSG2);
153
 
    }
154
 
    return 0;
155
 
}
156
 
 
157
 
unsigned Listen(unsigned long CIPmask) {
158
 
    return ListenOnController(CIPmask,0);
159
 
}
160
 
 
161
 
// Echo cancellation is for cards w/ integrated echo cancellation only
162
 
// (i.e. Eicon active cards support it)
163
 
 
164
 
#define EC_FUNCTION_ENABLE              1
165
 
#define EC_FUNCTION_DISABLE             2
166
 
#define EC_FUNCTION_FREEZE              3
167
 
#define EC_FUNCTION_RESUME              4
168
 
#define EC_FUNCTION_RESET               5
169
 
#define EC_OPTION_DISABLE_NEVER         0
170
 
#define EC_OPTION_DISABLE_G165          (1<<1)
171
 
#define EC_OPTION_DISABLE_G164_OR_G165  (1<<1 | 1<<2)
172
 
#define EC_DEFAULT_TAIL                 64
173
 
 
174
 
static int capi_echo_canceller(struct ast_channel *c, int function) {
175
 
    struct ast_capi_pvt *i = c->pvt->pvt;
176
 
    MESSAGE_EXCHANGE_ERROR  error;
177
 
    _cmsg                   CMSG;
178
 
    char   buf[7];
 
618
}
 
619
 
 
620
/*
 
621
 *  TCAP -> CIP Translation Table (TransferCapability->CommonIsdnProfile)
 
622
 */
 
623
static struct {
 
624
        unsigned short tcap;
 
625
        unsigned short cip;
 
626
        unsigned char digital;
 
627
} translate_tcap2cip[] = {
 
628
        { PRI_TRANS_CAP_SPEECH,                 CAPI_CIPI_SPEECH,               0 },
 
629
        { PRI_TRANS_CAP_DIGITAL,                CAPI_CIPI_DIGITAL,              1 },
 
630
        { PRI_TRANS_CAP_RESTRICTED_DIGITAL,     CAPI_CIPI_RESTRICTED_DIGITAL,   1 },
 
631
        { PRI_TRANS_CAP_3K1AUDIO,               CAPI_CIPI_3K1AUDIO,             0 },
 
632
        { PRI_TRANS_CAP_DIGITAL_W_TONES,        CAPI_CIPI_DIGITAL_W_TONES,      1 },
 
633
        { PRI_TRANS_CAP_VIDEO,                  CAPI_CIPI_VIDEO,                1 }
 
634
};
 
635
 
 
636
static int tcap2cip(unsigned short tcap)
 
637
{
 
638
        int x;
 
639
        
 
640
        for (x = 0; x < sizeof(translate_tcap2cip) / sizeof(translate_tcap2cip[0]); x++) {
 
641
                if (translate_tcap2cip[x].tcap == tcap)
 
642
                        return (int)translate_tcap2cip[x].cip;
 
643
        }
 
644
        return CAPI_CIPI_SPEECH;
 
645
}
 
646
 
 
647
static unsigned char tcap_is_digital(unsigned short tcap)
 
648
{
 
649
        int x;
 
650
        
 
651
        for (x = 0; x < sizeof(translate_tcap2cip) / sizeof(translate_tcap2cip[0]); x++) {
 
652
                if (translate_tcap2cip[x].tcap == tcap)
 
653
                        return translate_tcap2cip[x].digital;
 
654
        }
 
655
        return 0;
 
656
}
 
657
 
 
658
/*
 
659
 *  CIP -> TCAP Translation Table (CommonIsdnProfile->TransferCapability)
 
660
 */
 
661
static struct {
 
662
        unsigned short cip;
 
663
        unsigned short tcap;
 
664
} translate_cip2tcap[] = {
 
665
        { CAPI_CIPI_SPEECH,                  PRI_TRANS_CAP_SPEECH },
 
666
        { CAPI_CIPI_DIGITAL,                 PRI_TRANS_CAP_DIGITAL },
 
667
        { CAPI_CIPI_RESTRICTED_DIGITAL,      PRI_TRANS_CAP_RESTRICTED_DIGITAL },
 
668
        { CAPI_CIPI_3K1AUDIO,                PRI_TRANS_CAP_3K1AUDIO },
 
669
        { CAPI_CIPI_7KAUDIO,                 PRI_TRANS_CAP_DIGITAL_W_TONES },
 
670
        { CAPI_CIPI_VIDEO,                   PRI_TRANS_CAP_VIDEO },
 
671
        { CAPI_CIPI_PACKET_MODE,             PRI_TRANS_CAP_DIGITAL },
 
672
        { CAPI_CIPI_56KBIT_RATE_ADAPTION,    PRI_TRANS_CAP_DIGITAL },
 
673
        { CAPI_CIPI_DIGITAL_W_TONES,         PRI_TRANS_CAP_DIGITAL_W_TONES },
 
674
        { CAPI_CIPI_TELEPHONY,               PRI_TRANS_CAP_SPEECH },
 
675
        { CAPI_CIPI_FAX_G2_3,                PRI_TRANS_CAP_3K1AUDIO },
 
676
        { CAPI_CIPI_FAX_G4C1,                PRI_TRANS_CAP_DIGITAL },
 
677
        { CAPI_CIPI_FAX_G4C2_3,              PRI_TRANS_CAP_DIGITAL },
 
678
        { CAPI_CIPI_TELETEX_PROCESSABLE,     PRI_TRANS_CAP_DIGITAL },
 
679
        { CAPI_CIPI_TELETEX_BASIC,           PRI_TRANS_CAP_DIGITAL },
 
680
        { CAPI_CIPI_VIDEOTEX,                PRI_TRANS_CAP_DIGITAL },
 
681
        { CAPI_CIPI_TELEX,                   PRI_TRANS_CAP_DIGITAL },
 
682
        { CAPI_CIPI_X400,                    PRI_TRANS_CAP_DIGITAL },
 
683
        { CAPI_CIPI_X200,                    PRI_TRANS_CAP_DIGITAL },
 
684
        { CAPI_CIPI_7K_TELEPHONY,            PRI_TRANS_CAP_DIGITAL_W_TONES },
 
685
        { CAPI_CIPI_VIDEO_TELEPHONY_C1,      PRI_TRANS_CAP_DIGITAL_W_TONES },
 
686
        { CAPI_CIPI_VIDEO_TELEPHONY_C2,      PRI_TRANS_CAP_DIGITAL }
 
687
};
 
688
 
 
689
static unsigned short cip2tcap(int cip)
 
690
{
 
691
        int x;
 
692
        
 
693
        for (x = 0;x < sizeof(translate_cip2tcap) / sizeof(translate_cip2tcap[0]); x++) {
 
694
                if (translate_cip2tcap[x].cip == (unsigned short)cip)
 
695
                        return translate_cip2tcap[x].tcap;
 
696
        }
 
697
        return 0;
 
698
}
 
699
 
 
700
/*
 
701
 *  TransferCapability to String conversion
 
702
 */
 
703
static char *transfercapability2str(int transfercapability)
 
704
{
 
705
        switch(transfercapability) {
 
706
        case PRI_TRANS_CAP_SPEECH:
 
707
                return "SPEECH";
 
708
        case PRI_TRANS_CAP_DIGITAL:
 
709
                return "DIGITAL";
 
710
        case PRI_TRANS_CAP_RESTRICTED_DIGITAL:
 
711
                return "RESTRICTED_DIGITAL";
 
712
        case PRI_TRANS_CAP_3K1AUDIO:
 
713
                return "3K1AUDIO";
 
714
        case PRI_TRANS_CAP_DIGITAL_W_TONES:
 
715
                return "DIGITAL_W_TONES";
 
716
        case PRI_TRANS_CAP_VIDEO:
 
717
                return "VIDEO";
 
718
        default:
 
719
                return "UNKNOWN";
 
720
        }
 
721
}
 
722
 
 
723
/*
 
724
 * set task for a channel which need to be done out of lock
 
725
 * ( after the capi thread loop )
 
726
 */
 
727
static void capi_channel_task(struct ast_channel *c, int task)
 
728
{
 
729
        chan_for_task = c;
 
730
        channel_task = task;
 
731
 
 
732
        cc_verbose(4, 1, VERBOSE_PREFIX_4 "%s: set channel task to %d\n",
 
733
                c->name, task);
 
734
}
 
735
 
 
736
/*
 
737
 * Echo cancellation is for cards w/ integrated echo cancellation only
 
738
 * (i.e. Eicon active cards support it)
 
739
 */
 
740
#define EC_FUNCTION_ENABLE              1
 
741
#define EC_FUNCTION_DISABLE             2
 
742
#define EC_FUNCTION_FREEZE              3
 
743
#define EC_FUNCTION_RESUME              4
 
744
#define EC_FUNCTION_RESET               5
 
745
#define EC_OPTION_DISABLE_NEVER         0
 
746
#define EC_OPTION_DISABLE_G165          (1<<2)
 
747
#define EC_OPTION_DISABLE_G164_OR_G165  (1<<1 | 1<<2)
 
748
#define EC_DEFAULT_TAIL                 0 /* maximum */
 
749
 
 
750
static void capi_echo_canceller(struct ast_channel *c, int function)
 
751
{
 
752
        struct capi_pvt *i = CC_CHANNEL_PVT(c);
 
753
        _cmsg CMSG;
 
754
        char buf[10];
 
755
 
 
756
        if ((i->isdnstate & CAPI_ISDN_STATE_DISCONNECT))
 
757
                return;
 
758
 
 
759
        if (((function == EC_FUNCTION_ENABLE) && (i->isdnstate & CAPI_ISDN_STATE_EC)) ||
 
760
            ((function != EC_FUNCTION_ENABLE) && (!(i->isdnstate & CAPI_ISDN_STATE_EC)))) {
 
761
                cc_verbose(3, 1, VERBOSE_PREFIX_4 "%s: echo canceller (PLCI=%#x, function=%d) unchanged\n",
 
762
                        i->vname, i->PLCI, function);
 
763
                /* nothing to do */
 
764
                return;
 
765
        }
179
766
 
180
767
        /* If echo cancellation is not requested or supported, don't attempt to enable it */
181
 
        ast_mutex_lock(&contrlock);
182
768
        if (!capi_controllers[i->controller]->echocancel || !i->doEC) {
183
 
                ast_mutex_unlock(&contrlock);
184
 
                return 0;
185
 
        }
186
 
        ast_mutex_unlock(&contrlock);
187
 
 
188
 
        if (option_verbose > 2) 
189
 
                ast_verbose(VERBOSE_PREFIX_3 "Setting up echo canceller (PLCI=%#x, function=%d, options=%d, tail=%d)\n",i->PLCI,function,i->ecOption,i->ecTail);
190
 
 
191
 
        FACILITY_REQ_HEADER(&CMSG, ast_capi_ApplID, ast_capi_MessageNumber++, 0);
192
 
        FACILITY_REQ_NCCI(&CMSG) = i->NCCI;
193
 
        FACILITY_REQ_FACILITYSELECTOR(&CMSG) = 6; /* Echo canceller */
194
 
 
195
 
        buf[0]=6; /* msg size */
196
 
        buf[1]=function;
 
769
                return;
 
770
        }
 
771
 
 
772
        if (tcap_is_digital(c->transfercapability)) {
 
773
                cc_verbose(3, 1, VERBOSE_PREFIX_2 "%s: No echo canceller in digital mode (PLCI=%#x)\n",
 
774
                        i->vname, i->PLCI);
 
775
                return;
 
776
        }
 
777
 
 
778
        cc_verbose(3, 0, VERBOSE_PREFIX_2 "%s: Setting up echo canceller (PLCI=%#x, function=%d, options=%d, tail=%d)\n",
 
779
                        i->vname, i->PLCI, function, i->ecOption, i->ecTail);
 
780
 
 
781
        FACILITY_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(), 0);
 
782
        FACILITY_REQ_PLCI(&CMSG) = i->PLCI;
 
783
        FACILITY_REQ_FACILITYSELECTOR(&CMSG) = i->ecSelector;
 
784
 
 
785
        memset(buf, 0, sizeof(buf));
 
786
        buf[0] = 9; /* msg size */
 
787
        write_capi_word(&buf[1], function);
197
788
        if (function == EC_FUNCTION_ENABLE) {
198
 
                buf[3]=i->ecOption; /* bit field - ignore echo canceller disable tone */
199
 
                buf[5]=i->ecTail;   /* Tail length, ms */
200
 
        }
201
 
        else {
202
 
                buf[3]=0;
203
 
                buf[5]=0;
204
 
        }
205
 
 
206
 
        // Always null:
207
 
        buf[2]=0;
208
 
        buf[4]=0;
209
 
        buf[6]=0;
210
 
 
211
 
        FACILITY_REQ_FACILITYREQUESTPARAMETER(&CMSG) = buf;
 
789
                buf[3] = 6; /* echo cancel param struct size */
 
790
                write_capi_word(&buf[4], i->ecOption); /* bit field - ignore echo canceller disable tone */
 
791
                write_capi_word(&buf[6], i->ecTail);   /* Tail length, ms */
 
792
                /* buf 8 and 9 are "pre-delay lenght ms" */
 
793
                i->isdnstate |= CAPI_ISDN_STATE_EC;
 
794
        } else {
 
795
                i->isdnstate &= ~CAPI_ISDN_STATE_EC;
 
796
        }
 
797
 
 
798
        FACILITY_REQ_FACILITYREQUESTPARAMETER(&CMSG) = (_cstruct)buf;
212
799
        
213
 
        if ((error = _capi_put_cmsg(&CMSG)) != 0) {
214
 
            ast_log(LOG_ERROR,"error sending FACILITY_REQ (error=%#x)\n",error);
215
 
            return error;
 
800
        if (_capi_put_cmsg(&CMSG) != 0) {
 
801
                return;
216
802
        }
217
803
 
218
 
        if (option_verbose > 5) 
219
 
           ast_verbose(VERBOSE_PREFIX_4 "sent FACILITY_REQ (PLCI=%#x)\n",i->PLCI);
220
 
 
221
 
    return 0;
 
804
        return;
222
805
}
223
806
 
224
 
int capi_detect_dtmf(struct ast_channel *c, int flag) {
225
 
    struct ast_capi_pvt *i = c->pvt->pvt;
226
 
    MESSAGE_EXCHANGE_ERROR  error;
227
 
    _cmsg                   CMSG;
228
 
    char        buf[9];
229
 
#ifndef FORCE_SOFTWARE_DTMF
230
 
    // does the controller support dtmf? and do we want to use it?
231
 
    ast_mutex_lock(&contrlock);
232
 
    if ((capi_controllers[i->controller]->dtmf == 1) && (i->doDTMF == 0)) {
233
 
        ast_mutex_unlock(&contrlock);
234
 
        FACILITY_REQ_HEADER(&CMSG, ast_capi_ApplID, ast_capi_MessageNumber++, 0);
 
807
/*
 
808
 * turn on/off DTMF detection
 
809
 */
 
810
static int capi_detect_dtmf(struct ast_channel *c, int flag)
 
811
{
 
812
        struct capi_pvt *i = CC_CHANNEL_PVT(c);
 
813
        MESSAGE_EXCHANGE_ERROR error;
 
814
        _cmsg CMSG;
 
815
        char buf[9];
 
816
 
 
817
        if ((i->isdnstate & CAPI_ISDN_STATE_DISCONNECT))
 
818
                return 0;
 
819
 
 
820
        if (tcap_is_digital(c->transfercapability)) {
 
821
                cc_verbose(3, 1, VERBOSE_PREFIX_2 "%s: No dtmf-detect in digital mode (PLCI=%#x)\n",
 
822
                        i->vname, i->PLCI);
 
823
                return 0;
 
824
        }
 
825
 
 
826
        if (((flag == 1) && (i->isdnstate & CAPI_ISDN_STATE_DTMF)) ||
 
827
            ((flag == 0) && (!(i->isdnstate & CAPI_ISDN_STATE_DTMF)))) {
 
828
                cc_verbose(3, 1, VERBOSE_PREFIX_4 "%s: dtmf (PLCI=%#x, flag=%d) unchanged\n",
 
829
                        i->vname, i->PLCI, flag);
 
830
                /* nothing to do */
 
831
                return 0;
 
832
        }
 
833
        
 
834
        /* does the controller support dtmf? and do we want to use it? */
 
835
        if ((capi_controllers[i->controller]->dtmf != 1) || (i->doDTMF != 0))
 
836
                return 0;
 
837
        
 
838
        memset(buf, 0, sizeof(buf));
 
839
        cc_verbose(3, 0, VERBOSE_PREFIX_2 "%s: Setting up DTMF detector (PLCI=%#x, flag=%d)\n",
 
840
                i->vname, i->PLCI, flag);
 
841
        FACILITY_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(), 0);
235
842
        FACILITY_REQ_PLCI(&CMSG) = i->PLCI;
236
 
        FACILITY_REQ_FACILITYSELECTOR(&CMSG) = 1;
237
 
        buf[0] = 8;
 
843
        FACILITY_REQ_FACILITYSELECTOR(&CMSG) = FACILITYSELECTOR_DTMF;
 
844
        buf[0] = 8; /* msg length */
238
845
        if (flag == 1) {
239
 
            buf[1] = 1;
 
846
                write_capi_word(&buf[1], 1); /* start DTMF listen */
240
847
        } else {
241
 
            buf[1] = 2;
 
848
                write_capi_word(&buf[1], 2); /* stop DTMF listen */
242
849
        }
243
 
        buf[2] = 0;
244
 
        buf[3] = AST_CAPI_DTMF_DURATION;
245
 
        buf[4] = 0;
246
 
        buf[5] = AST_CAPI_DTMF_DURATION;
247
 
        buf[6] = 0;
248
 
        buf[7] = 0;
249
 
        buf[8] = 0;
250
 
        FACILITY_REQ_FACILITYREQUESTPARAMETER(&CMSG) = buf;
 
850
        write_capi_word(&buf[3], CAPI_DTMF_DURATION);
 
851
        write_capi_word(&buf[5], CAPI_DTMF_DURATION);
 
852
        FACILITY_REQ_FACILITYREQUESTPARAMETER(&CMSG) = (_cstruct)buf;
251
853
        
252
854
        if ((error = _capi_put_cmsg(&CMSG)) != 0) {
253
 
            ast_log(LOG_ERROR,"error sending FACILITY_REQ (error=%#x)\n",error);
254
 
            return error;
 
855
                return error;
 
856
        }
 
857
        if (flag == 1) {
 
858
                i->isdnstate |= CAPI_ISDN_STATE_DTMF;
255
859
        } else {
256
 
            if (option_verbose > 5) {
257
 
                ast_verbose(VERBOSE_PREFIX_4 "sent FACILITY_REQ (PLCI=%#x)\n",i->PLCI);
258
 
            }
259
 
        }
260
 
    } else {
261
 
        ast_mutex_unlock(&contrlock);
262
 
 
263
 
#endif
264
 
        // do software dtmf detection
265
 
        i->doDTMF = 1; // just being paranoid again...
266
 
#ifndef FORCE_SOFTWARE_DTMF
267
 
    }
268
 
#endif
269
 
    return 0;
270
 
}
271
 
static int capi_send_digit(struct ast_channel *c,char digit) {
272
 
    struct ast_capi_pvt *i = c->pvt->pvt;
273
 
    MESSAGE_EXCHANGE_ERROR  error;
274
 
    _cmsg                   CMSG;
275
 
    char        buf[10];
276
 
    
277
 
    if (i->state != CAPI_STATE_BCONNECTED) {
278
 
        return 0;
279
 
    }
280
 
    
281
 
    
282
 
#ifndef NEVER_EVER_EARLY_B3_CONNECTS
283
 
    if(i->earlyB3 == 1)
284
 
    /* we should really test for the network saying the number is incomplete
285
 
    since i'm only doing a test and this is true at the right time
286
 
    i'm going with this */
287
 
    {
288
 
 
289
 
        INFO_REQ_HEADER(&CMSG, ast_capi_ApplID, ast_capi_MessageNumber++, 0);
 
860
                i->isdnstate &= ~CAPI_ISDN_STATE_DTMF;
 
861
        }
 
862
        return 0;
 
863
}
 
864
 
 
865
/*
 
866
 * queue a frame to PBX
 
867
 */
 
868
static int local_queue_frame(struct capi_pvt *i, struct ast_frame *f)
 
869
{
 
870
        struct ast_channel *chan = i->owner;
 
871
        unsigned char *wbuf;
 
872
        int wbuflen;
 
873
 
 
874
        if (chan == NULL) {
 
875
                cc_log(LOG_ERROR, "No owner in local_queue_frame for %s\n",
 
876
                        i->vname);
 
877
                return -1;
 
878
        }
 
879
 
 
880
        if (!(i->isdnstate & CAPI_ISDN_STATE_PBX)) {
 
881
                /* if there is no PBX running yet,
 
882
                   we don't need any frames sent */
 
883
                return -1;
 
884
        }
 
885
        if ((i->state == CAPI_STATE_DISCONNECTING) ||
 
886
            (i->isdnstate & CAPI_ISDN_STATE_HANGUP)) {
 
887
                cc_verbose(3, 1, VERBOSE_PREFIX_4 "%s: no queue_frame in state disconnecting for %d/%d\n",
 
888
                        i->vname, f->frametype, f->subclass);
 
889
                return 0;
 
890
        }
 
891
 
 
892
        if ((capidebug) && (f->frametype != AST_FRAME_VOICE)) {
 
893
                ast_frame_dump(i->vname, f, VERBOSE_PREFIX_3 "CAPI queue frame:");
 
894
        }
 
895
 
 
896
        if ((f->frametype == AST_FRAME_CONTROL) &&
 
897
            (f->subclass == AST_CONTROL_HANGUP)) {
 
898
                i->isdnstate |= CAPI_ISDN_STATE_HANGUP;
 
899
        }
 
900
 
 
901
        if (i->writerfd == -1) {
 
902
                cc_log(LOG_ERROR, "No writerfd in local_queue_frame for %s\n",
 
903
                        i->vname);
 
904
                return -1;
 
905
        }
 
906
 
 
907
        if (f->frametype != AST_FRAME_VOICE)
 
908
                f->datalen = 0;
 
909
 
 
910
        wbuflen = sizeof(struct ast_frame) + f->datalen;
 
911
        wbuf = alloca(wbuflen);
 
912
        memcpy(wbuf, f, sizeof(struct ast_frame));
 
913
        if (f->datalen)
 
914
                memcpy(wbuf + sizeof(struct ast_frame), f->data, f->datalen);
 
915
 
 
916
        if (write(i->writerfd, wbuf, wbuflen) != wbuflen) {
 
917
                cc_log(LOG_ERROR, "Could not write to pipe for %s\n",
 
918
                        i->vname);
 
919
        }
 
920
        return 0;
 
921
}
 
922
 
 
923
/*
 
924
 * set a new name for this channel
 
925
 */
 
926
static void update_channel_name(struct capi_pvt *i)
 
927
{
 
928
        char name[AST_CHANNEL_NAME];
 
929
 
 
930
        snprintf(name, sizeof(name) - 1, "CAPI/%s/%s-%x",
 
931
                i->name, i->dnid, capi_counter++);
 
932
        ast_change_name(i->owner, name);
 
933
        cc_verbose(3, 0, VERBOSE_PREFIX_3 "%s: Updated channel name: %s\n",
 
934
                        i->vname, name);
 
935
}
 
936
 
 
937
/*
 
938
 * send digits via INFO_REQ
 
939
 */
 
940
static int capi_send_info_digits(struct capi_pvt *i, char *digits, int len)
 
941
{
 
942
        MESSAGE_EXCHANGE_ERROR error;
 
943
        _cmsg CMSG;
 
944
        char buf[64];
 
945
        int a;
 
946
    
 
947
        memset(buf, 0, sizeof(buf));
 
948
 
 
949
        INFO_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(), 0);
290
950
        INFO_REQ_PLCI(&CMSG) = i->PLCI;
291
 
        buf[0] = 2;
 
951
 
 
952
        if (len > (sizeof(buf) - 2))
 
953
                len = sizeof(buf) - 2;
 
954
        
 
955
        buf[0] = len + 1;
292
956
        buf[1] = 0x80;
293
 
        buf[2] = digit;
294
 
        INFO_REQ_CALLEDPARTYNUMBER(&CMSG) = buf;
295
 
 
 
957
        for (a = 0; a < len; a++) {
 
958
                buf[a + 2] = digits[a];
 
959
        }
 
960
        INFO_REQ_CALLEDPARTYNUMBER(&CMSG) = (_cstruct)buf;
296
961
 
297
962
        if ((error = _capi_put_cmsg(&CMSG)) != 0) {
298
 
            ast_log(LOG_ERROR,"error sending CALLEDPARTYNUMBER INFO (error=%#x)\n",error);
299
 
            return error;
300
 
        } else {
301
 
            if (option_verbose > 5) {
302
 
                ast_verbose(VERBOSE_PREFIX_4 "sent CALLEDPARTYNUMBER INFO digit = %c (PLCI=%#x)\n", digit, i->PLCI);
303
 
            }
304
 
        }
305
 
 
306
 
    } else {
307
 
#endif
308
 
#ifndef FORCE_SOFTWARE_DTMF
309
 
        ast_mutex_lock(&contrlock);
310
 
        if ((capi_controllers[i->controller]->dtmf == 0) || (i->doDTMF == 1)) {
311
 
#endif
312
 
            // let * fake it
313
 
#ifndef FORCE_SOFTWARE_DTMF
314
 
            ast_mutex_unlock(&contrlock);
315
 
#endif
316
 
            return -1;
317
 
#ifndef FORCE_SOFTWARE_DTMF
318
 
        }
319
 
        ast_mutex_unlock(&contrlock);
320
 
        
321
 
        FACILITY_REQ_HEADER(&CMSG, ast_capi_ApplID, ast_capi_MessageNumber++, 0);
322
 
        FACILITY_REQ_PLCI(&CMSG) = i->NCCI;
323
 
        FACILITY_REQ_FACILITYSELECTOR(&CMSG) = 1;
324
 
        buf[0] = 8;
325
 
    
326
 
        buf[1] = 3;
327
 
        buf[2] = 0;
328
 
    
329
 
        buf[3] = AST_CAPI_DTMF_DURATION;
330
 
        buf[4] = 0;
331
 
    
332
 
        buf[5] = AST_CAPI_DTMF_DURATION;
333
 
        buf[6] = 0;
334
 
    
335
 
        buf[7] = 1;
336
 
        buf[8] = digit;
337
 
        buf[9] = 0;
338
 
        FACILITY_REQ_FACILITYREQUESTPARAMETER(&CMSG) = buf;
 
963
                return error;
 
964
        }
 
965
        cc_verbose(3, 1, VERBOSE_PREFIX_4 "%s: sent CALLEDPARTYNUMBER INFO digits = '%s' (PLCI=%#x)\n",
 
966
                i->vname, buf + 2, i->PLCI);
 
967
        return 0;
 
968
}
 
969
 
 
970
/*
 
971
 * send a DTMF digit
 
972
 */
 
973
static int pbx_capi_send_digit(struct ast_channel *c, char digit)
 
974
{
 
975
        struct capi_pvt *i = CC_CHANNEL_PVT(c);
 
976
        _cmsg CMSG;
 
977
        char buf[10];
 
978
        char did[2];
 
979
        int ret = 0;
 
980
    
 
981
        if (i == NULL) {
 
982
                cc_log(LOG_ERROR, "No interface!\n");
 
983
                return -1;
 
984
        }
 
985
 
 
986
        memset(buf, 0, sizeof(buf));
 
987
 
 
988
        cc_mutex_lock(&i->lock);
 
989
 
 
990
        if ((c->_state == AST_STATE_DIALING) &&
 
991
            (i->state != CAPI_STATE_DISCONNECTING)) {
 
992
                did[0] = digit;
 
993
                did[1] = 0;
 
994
                strncat(i->dnid, did, sizeof(i->dnid) - 1);
 
995
                update_channel_name(i); 
 
996
                if ((i->isdnstate & CAPI_ISDN_STATE_SETUP_ACK) &&
 
997
                    (i->doOverlap == 0)) {
 
998
                        ret = capi_send_info_digits(i, &digit, 1);
 
999
                } else {
 
1000
                        /* if no SETUP-ACK yet, add it to the overlap list */
 
1001
                        strncat(i->overlapdigits, &digit, 1);
 
1002
                        i->doOverlap = 1;
 
1003
                }
 
1004
                cc_mutex_unlock(&i->lock);
 
1005
                return ret;
 
1006
        }
 
1007
 
 
1008
        if ((i->state == CAPI_STATE_CONNECTED) && (i->isdnstate & CAPI_ISDN_STATE_B3_UP)) {
 
1009
                /* we have a real connection, so send real DTMF */
 
1010
                if ((capi_controllers[i->controller]->dtmf == 0) || (i->doDTMF > 0)) {
 
1011
                        /* let * fake it */
 
1012
                        cc_mutex_unlock(&i->lock);
 
1013
                        return -1;
 
1014
                }
 
1015
                
 
1016
                FACILITY_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(), 0);
 
1017
                FACILITY_REQ_PLCI(&CMSG) = i->NCCI;
 
1018
                FACILITY_REQ_FACILITYSELECTOR(&CMSG) = FACILITYSELECTOR_DTMF;
 
1019
                buf[0] = 8;
 
1020
                write_capi_word(&buf[1], 3); /* send DTMF digit */
 
1021
                write_capi_word(&buf[3], CAPI_DTMF_DURATION);
 
1022
                write_capi_word(&buf[5], CAPI_DTMF_DURATION);
 
1023
                buf[7] = 1;
 
1024
                buf[8] = digit;
 
1025
                FACILITY_REQ_FACILITYREQUESTPARAMETER(&CMSG) = (_cstruct)buf;
339
1026
        
340
 
        if ((error = _capi_put_cmsg(&CMSG)) != 0) {
341
 
            ast_log(LOG_ERROR,"error sending FACILITY_REQ (error=%#x)\n",error);
342
 
            return error;
343
 
        } else {
344
 
            if (option_verbose > 4) {
345
 
                ast_verbose(VERBOSE_PREFIX_3 "sent dtmf '%c'\n",digit);
346
 
            }
347
 
        }
348
 
#endif
349
 
#ifndef NEVER_EVER_EARLY_B3_CONNECTS
350
 
    }
351
 
#endif
352
 
    return 0;
353
 
}
354
 
 
355
 
static int capi_alert(struct ast_channel *c) {
356
 
    struct ast_capi_pvt *i = c->pvt->pvt;
357
 
    MESSAGE_EXCHANGE_ERROR  error;
358
 
    _cmsg       CMSG;
359
 
    
360
 
    ALERT_REQ_HEADER(&CMSG, ast_capi_ApplID, i->MessageNumber, 0);
361
 
    ALERT_REQ_PLCI(&CMSG) = i->PLCI;
362
 
 
363
 
    if ((error = _capi_put_cmsg(&CMSG)) != 0) {
364
 
        ast_log(LOG_ERROR,"error sending ALERT_REQ PLCI = %#x\n",i->PLCI);
365
 
        return -1;
366
 
    } else {
367
 
        if (option_verbose > 5) {
368
 
            ast_verbose(VERBOSE_PREFIX_4 "sent ALERT_REQ PLCI = %#x\n",i->PLCI);
369
 
        }
370
 
    }
371
 
 
372
 
    i->state = CAPI_STATE_ALERTING;
373
 
    return 0;
374
 
}
375
 
 
376
 
#ifdef DEFLECT_ON_CIRCUITBUSY
377
 
static int capi_deflect(struct ast_channel *chan, void *data)
378
 
{
379
 
    struct ast_capi_pvt *i = chan->pvt->pvt;
380
 
    MESSAGE_EXCHANGE_ERROR Info;
381
 
    _cmsg       CMSG;
382
 
    char        bchaninfo[1];
383
 
    char        fac[60];
384
 
    int res=0;
385
 
    int ms=3000;
386
 
 
387
 
    if (!data) {
388
 
        ast_log(LOG_WARNING, "cd requires an argument (destination phone number)\n");
389
 
        return -1;
390
 
    }
391
 
 
392
 
    if ((i->state == CAPI_STATE_CONNECTED) || (i->state == CAPI_STATE_BCONNECTED)) {
393
 
        ast_log(LOG_ERROR, "call deflection does not work with calls that are already connected!\n");
394
 
        return -1;
395
 
    }
396
 
    // wait until the channel is alerting, so we dont drop the call and interfer with msgs
397
 
    while ((ms > 0) && (i->state != CAPI_STATE_ALERTING)) {
398
 
        sleep(100);
399
 
        ms -= 100;
400
 
    }
401
 
 
402
 
    // make sure we hang up correctly
403
 
    i->state = CAPI_STATE_CONNECTPENDING;
404
 
 
405
 
    fac[0]=0; // len 
406
 
    fac[1]=0; //len 
407
 
    fac[2]=0x01; // Use D-Chan
408
 
    fac[3]=0; // Keypad len
409
 
    fac[4]=31;  // user user data? len = 31 = 29 + 2
410
 
    fac[5]=0x1c;        // magic?
411
 
    fac[6]=0x1d;        // strlen destination + 18 = 29
412
 
    fac[7]=0x91;        // ..
413
 
    fac[8]=0xA1;
414
 
    fac[9]=0x1A;        // strlen destination + 15 = 26
415
 
    fac[10]=0x02;
416
 
    fac[11]=0x01;
417
 
    fac[12]=0x70;
418
 
    fac[13]=0x02;
419
 
    fac[14]=0x01;
420
 
    fac[15]=0x0d;
421
 
    fac[16]=0x30;
422
 
    fac[17]=0x12;       // strlen destination + 7 = 18
423
 
    fac[18]=0x30;       // ...hm 0x30
424
 
    fac[19]=0x0d;       // strlen destination + 2       
425
 
    fac[20]=0x80;       // CLIP
426
 
    fac[21]=0x0b;       //  strlen destination 
427
 
    fac[22]=0x01;       //  destination start
428
 
    fac[23]=0x01;       //  
429
 
    fac[24]=0x01;       //  
430
 
    fac[25]=0x01;       //  
431
 
    fac[26]=0x01;       //  
432
 
    fac[27]=0x01;       //  
433
 
    fac[28]=0x01;       //  
434
 
    fac[29]=0x01;       //  
435
 
    fac[30]=0x01;       //  
436
 
    fac[31]=0x01;       //  
437
 
    fac[32]=0x01;       //  
438
 
    fac[33]=0x01;       // 0x1 = sending complete
439
 
    fac[34]=0x01;
440
 
    fac[35]=0x01;
441
 
                                   
442
 
    memcpy((unsigned char *)fac+22,data,strlen(data));
443
 
    fac[22+strlen(data)]=0x01;  // fill with 0x01 if number is only 6 numbers (local call)
444
 
    fac[23+strlen(data)]=0x01;
445
 
    fac[24+strlen(data)]=0x01;
446
 
    fac[25+strlen(data)]=0x01;
447
 
    fac[26+strlen(data)]=0x01;
448
 
     
449
 
    fac[6]=18+strlen(data);
450
 
    fac[9]=15+strlen(data);
451
 
    fac[17]=7+strlen(data);
452
 
    fac[19]=2+strlen(data);
453
 
    fac[21]=strlen(data);
454
 
 
455
 
    bchaninfo[0] = 0x1;
456
 
    INFO_REQ_HEADER(&CMSG,ast_capi_ApplID,ast_capi_MessageNumber++,0);
457
 
    INFO_REQ_CONTROLLER(&CMSG) = i->controller;
458
 
    INFO_REQ_PLCI(&CMSG) = i->PLCI;
459
 
    INFO_REQ_BCHANNELINFORMATION(&CMSG) = (unsigned char*)bchaninfo; // use D-Channel
460
 
    INFO_REQ_KEYPADFACILITY(&CMSG) = 0;
461
 
    INFO_REQ_USERUSERDATA(&CMSG) = 0;
462
 
    INFO_REQ_FACILITYDATAARRAY(&CMSG) = (unsigned char*) fac + 4;
463
 
 
464
 
    if ((Info = _capi_put_cmsg(&CMSG)) != 0) {
465
 
        ast_log(LOG_ERROR,"Error sending INFO_REQ\n");
466
 
        return Info;
467
 
    } else {
468
 
        if (capidebug) {
469
 
            // ast_log(LOG_NOTICE,"%s\n",capi_cmsg2str(&CMSG));
470
 
            ast_log(LOG_NOTICE,"sent INFO_REQ PLCI = %#x\n",i->PLCI);
471
 
        }
472
 
    }
473
 
 
474
 
    return res;
475
 
}
476
 
#endif
477
 
 
478
 
void remove_pipe(int PLCI) {
479
 
    struct capi_pipe *p,*ptmp;
480
 
 
481
 
    ast_mutex_lock(&pipelock);
482
 
    p = pipelist;
483
 
    ptmp = NULL;
484
 
    while (p) {
485
 
        if (p->PLCI == PLCI) {
486
 
            if (ptmp == NULL) {
487
 
                // mypipe == head of pipelist
488
 
                pipelist = p->next;
489
 
                if(p->fd > -1) close(p->fd);
490
 
                if(p->i != NULL && p->i->fd > -1) close(p->i->fd);
491
 
                free(p);
492
 
                if (option_verbose > 4) {
493
 
                    ast_verbose(VERBOSE_PREFIX_3 "removed pipe for PLCI = %#x\n",PLCI);
494
 
                }
495
 
                break;
496
 
            } else {
497
 
                // somehwere inbetween or at the end
498
 
                ptmp->next = p->next;
499
 
                if (p->next == NULL) {
500
 
                    capi_last_plci = p->PLCI;
501
 
                }
502
 
                if(p->fd > -1) close(p->fd);
503
 
                if(p->i != NULL && p->i->fd > -1) close(p->i->fd);
504
 
                free(p);
505
 
                if (option_verbose > 4) {
506
 
                    ast_verbose(VERBOSE_PREFIX_3 "removed pipe for PLCI = %#x\n",PLCI);
507
 
                }
508
 
                break;
509
 
            }
510
 
        }
511
 
        ptmp = p;
512
 
        p = p->next;
513
 
    }
514
 
    ast_mutex_unlock(&pipelock);
515
 
}
516
 
 
517
 
static int capi_activehangup(struct ast_channel *c) {
518
 
    struct ast_capi_pvt *i;
519
 
    MESSAGE_EXCHANGE_ERROR  error;
520
 
    _cmsg       CMSG;
521
 
    i = c->pvt->pvt;
522
 
 
523
 
    if (option_verbose > 2) {
524
 
        if (capidebug)
525
 
            ast_verbose(VERBOSE_PREFIX_4 "activehangingup\n");
526
 
    }
527
 
 
528
 
    if (i == NULL) {
529
 
        return 0;
530
 
    }
531
 
 
532
 
    if (c->_state == AST_STATE_RING) {
533
 
        CONNECT_RESP_HEADER(&CMSG, ast_capi_ApplID, i->MessageNumber, 0);
534
 
        CONNECT_RESP_PLCI(&CMSG) = i->PLCI;
535
 
        CONNECT_RESP_REJECT(&CMSG) = 2;
536
 
        if ((error = _capi_put_cmsg(&CMSG)) != 0) {
537
 
            ast_log(LOG_ERROR,"error sending CONNECT_RESP for PLCI = %#x\n",i->PLCI);
538
 
        } else {
539
 
            if (option_verbose > 5) {
540
 
                ast_verbose(VERBOSE_PREFIX_4 "sent CONNECT_RESP for PLCI = %#x\n",i->PLCI);
541
 
            }
542
 
        }
543
 
        return 0;
544
 
    }
545
 
 
546
 
    // active disconnect
547
 
    if (i->state == CAPI_STATE_BCONNECTED) {
548
 
        DISCONNECT_B3_REQ_HEADER(&CMSG, ast_capi_ApplID, ast_capi_MessageNumber++, 0);
 
1027
                if ((ret = _capi_put_cmsg(&CMSG)) == 0) {
 
1028
                        cc_verbose(3, 0, VERBOSE_PREFIX_4 "%s: sent dtmf '%c'\n",
 
1029
                                i->vname, digit);
 
1030
                }
 
1031
        }
 
1032
        cc_mutex_unlock(&i->lock);
 
1033
        return ret;
 
1034
}
 
1035
 
 
1036
/*
 
1037
 * send ALERT to ISDN line
 
1038
 */
 
1039
static int pbx_capi_alert(struct ast_channel *c)
 
1040
{
 
1041
        struct capi_pvt *i = CC_CHANNEL_PVT(c);
 
1042
        _cmsg CMSG;
 
1043
 
 
1044
        if ((i->state != CAPI_STATE_INCALL) &&
 
1045
            (i->state != CAPI_STATE_DID)) {
 
1046
                cc_verbose(2, 1, VERBOSE_PREFIX_3 "%s: attempting ALERT in state %d\n",
 
1047
                        i->vname, i->state);
 
1048
                return -1;
 
1049
        }
 
1050
        
 
1051
        ALERT_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(), 0);
 
1052
        ALERT_REQ_PLCI(&CMSG) = i->PLCI;
 
1053
 
 
1054
        if (_capi_put_cmsg(&CMSG) != 0) {
 
1055
                return -1;
 
1056
        }
 
1057
 
 
1058
        i->state = CAPI_STATE_ALERTING;
 
1059
        ast_setstate(c, AST_STATE_RING);
 
1060
        
 
1061
        return 0;
 
1062
}
 
1063
 
 
1064
/*
 
1065
 * cleanup the interface
 
1066
 */
 
1067
static void interface_cleanup(struct capi_pvt *i)
 
1068
{
 
1069
        if (!i)
 
1070
                return;
 
1071
 
 
1072
        cc_verbose(2, 1, VERBOSE_PREFIX_2 "%s: Interface cleanup PLCI=%#x\n",
 
1073
                i->vname, i->PLCI);
 
1074
 
 
1075
        if (i->readerfd != -1) {
 
1076
                close(i->readerfd);
 
1077
                i->readerfd = -1;
 
1078
        }
 
1079
        if (i->writerfd != -1) {
 
1080
                close(i->writerfd);
 
1081
                i->writerfd = -1;
 
1082
        }
 
1083
 
 
1084
        i->isdnstate = 0;
 
1085
        i->cause = 0;
 
1086
 
 
1087
        i->FaxState &= ~CAPI_FAX_STATE_MASK;
 
1088
 
 
1089
        i->PLCI = 0;
 
1090
        i->MessageNumber = 0;
 
1091
        i->NCCI = 0;
 
1092
        i->onholdPLCI = 0;
 
1093
 
 
1094
        memset(i->cid, 0, sizeof(i->cid));
 
1095
        memset(i->dnid, 0, sizeof(i->dnid));
 
1096
        i->cid_ton = 0;
 
1097
 
 
1098
        i->rtpcodec = 0;
 
1099
        if (i->rtp) {
 
1100
                ast_rtp_destroy(i->rtp);
 
1101
                i->rtp = NULL;
 
1102
        }
 
1103
 
 
1104
        i->owner = NULL;
 
1105
        return;
 
1106
}
 
1107
 
 
1108
/*
 
1109
 * disconnect b3 and wait for confirmation 
 
1110
 */
 
1111
static void cc_disconnect_b3(struct capi_pvt *i, int wait) 
 
1112
{
 
1113
        _cmsg CMSG;
 
1114
        struct timespec abstime;
 
1115
 
 
1116
        if (!(i->isdnstate & (CAPI_ISDN_STATE_B3_UP | CAPI_ISDN_STATE_B3_PEND)))
 
1117
                return;
 
1118
 
 
1119
        cc_mutex_lock(&i->lock);
 
1120
        DISCONNECT_B3_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(), 0);
549
1121
        DISCONNECT_B3_REQ_NCCI(&CMSG) = i->NCCI;
550
 
 
551
 
        if ((error = _capi_put_cmsg(&CMSG)) != 0) {
552
 
            ast_log(LOG_ERROR, "error sending DISCONNECT_B3_REQ NCCI=%#x\n",i->NCCI);
553
 
        } else {
554
 
            if (option_verbose > 5) {
555
 
                ast_verbose(VERBOSE_PREFIX_4 "sent DISCONNECT_B3_REQ NCCI=%#x\n",i->NCCI);
556
 
            }
557
 
        }
558
 
        // wait for the B3 layer to go down
559
 
        while (i->state != CAPI_STATE_CONNECTED) {
560
 
            usleep(10000);
561
 
        }
562
 
    }
563
 
    if ((i->state == CAPI_STATE_CONNECTED) || (i->state == CAPI_STATE_CONNECTPENDING)){
564
 
        DISCONNECT_REQ_HEADER(&CMSG, ast_capi_ApplID, ast_capi_MessageNumber++, 0);
565
 
        DISCONNECT_REQ_PLCI(&CMSG) = i->PLCI;
566
 
 
567
 
        if ((error = _capi_put_cmsg(&CMSG)) != 0) {
568
 
            ast_log(LOG_ERROR, "error sending DISCONNECT_REQ PLCI=%#x\n",i->PLCI);
569
 
        } else {
570
 
            if (option_verbose > 5) {
571
 
                ast_verbose(VERBOSE_PREFIX_4 "sent DISCONNECT_REQ PLCI=%#x\n",i->PLCI);
572
 
            }
573
 
        }
574
 
        // wait for the B1 layer to go down
575
 
        while (i->state != CAPI_STATE_DISCONNECTED) {
576
 
            usleep(10000);
577
 
        }
578
 
    }
579
 
    return 0;
580
 
}
581
 
 
582
 
static int capi_hangup(struct ast_channel *c) {
583
 
    struct ast_capi_pvt *i;
584
 
    i = c->pvt->pvt;
585
 
 
586
 
    // hmm....ok...this is called to free the capi interface (passive disconnect)
587
 
    // or to bring down the channel (active disconnect)
588
 
    
589
 
    if (option_verbose > 3)
590
 
            ast_verbose(VERBOSE_PREFIX_3 "CAPI Hangingup\n");
591
 
 
592
 
    if (i == NULL) {
593
 
        ast_log(LOG_ERROR,"channel has no interface!\n");
594
 
        return -1;
595
 
    }
596
 
    
597
 
    // are we down, yet?
598
 
    if (i->state != CAPI_STATE_DISCONNECTED) {
599
 
        // no
600
 
        capi_activehangup(c);
601
 
    }
602
 
 
603
 
    remove_pipe(i->PLCI);
604
 
    i->PLCI = 0;
605
 
    i->NCCI = 0;
606
 
    if ((i->doDTMF == 1) && (i->vad != NULL)) {
607
 
        ast_dsp_free(i->vad);
608
 
    }
609
 
    ast_smoother_free(i->smoother); // discard any frames left hanging
610
 
    i->smoother=ast_smoother_new(AST_CAPI_MAX_B3_BLOCK_SIZE * 2);
611
 
    memset(i->cid,0,sizeof(i->cid));
612
 
    i->owner=NULL;
613
 
    ast_mutex_lock(&usecnt_lock);
 
1122
        _capi_put_cmsg_wait_conf(i, &CMSG);
 
1123
 
 
1124
        if (!wait) {
 
1125
                cc_mutex_unlock(&i->lock);
 
1126
                return;
 
1127
        }
 
1128
        
 
1129
        /* wait for the B3 layer to go down */
 
1130
        if ((i->isdnstate & (CAPI_ISDN_STATE_B3_UP | CAPI_ISDN_STATE_B3_PEND))) {
 
1131
                i->waitevent = CAPI_WAITEVENT_B3_DOWN;
 
1132
                abstime.tv_sec = time(NULL) + 2;
 
1133
                abstime.tv_nsec = 0;
 
1134
                cc_verbose(4, 1, "%s: wait for b3 down.\n",
 
1135
                        i->vname);
 
1136
                if (ast_cond_timedwait(&i->event_trigger, &i->lock, &abstime) != 0) {
 
1137
                        cc_log(LOG_WARNING, "%s: timed out waiting for b3 down.\n",
 
1138
                                i->vname);
 
1139
                } else {
 
1140
                        cc_verbose(4, 1, "%s: cond signal received for b3 down.\n",
 
1141
                                i->vname);
 
1142
                }
 
1143
        }
 
1144
        cc_mutex_unlock(&i->lock);
 
1145
        if ((i->isdnstate & CAPI_ISDN_STATE_B3_UP)) {
 
1146
                cc_log(LOG_ERROR, "capi disconnect b3: didn't disconnect NCCI=0x%08x\n",
 
1147
                        i->NCCI);
 
1148
        }
 
1149
        return;
 
1150
}
 
1151
 
 
1152
/*
 
1153
 * send CONNECT_B3_REQ
 
1154
 */
 
1155
static void cc_start_b3(struct capi_pvt *i)
 
1156
{
 
1157
        _cmsg CMSG;
 
1158
 
 
1159
        if (!(i->isdnstate & (CAPI_ISDN_STATE_B3_UP | CAPI_ISDN_STATE_B3_PEND))) {
 
1160
                i->isdnstate |= CAPI_ISDN_STATE_B3_PEND;
 
1161
                CONNECT_B3_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(), 0);
 
1162
                CONNECT_B3_REQ_PLCI(&CMSG) = i->PLCI;
 
1163
                CONNECT_B3_REQ_NCPI(&CMSG) = capi_rtp_ncpi(i);
 
1164
                _capi_put_cmsg(&CMSG);
 
1165
                cc_verbose(4, 1, VERBOSE_PREFIX_3 "%s: sent CONNECT_B3_REQ PLCI=%#x\n",
 
1166
                        i->vname, i->PLCI);
 
1167
        }
 
1168
}
 
1169
 
 
1170
/*
 
1171
 * start early B3
 
1172
 */
 
1173
static void start_early_b3(struct capi_pvt *i)
 
1174
{
 
1175
        if (i->doB3 != CAPI_B3_DONT) { 
 
1176
                /* we do early B3 Connect */
 
1177
                cc_start_b3(i);
 
1178
        }
 
1179
}
 
1180
 
 
1181
/*
 
1182
 * signal 'progress' to PBX 
 
1183
 */
 
1184
static void send_progress(struct capi_pvt *i)
 
1185
{
 
1186
        struct ast_frame fr = { AST_FRAME_CONTROL, };
 
1187
 
 
1188
        start_early_b3(i);
 
1189
 
 
1190
        if (!(i->isdnstate & CAPI_ISDN_STATE_PROGRESS)) {
 
1191
                i->isdnstate |= CAPI_ISDN_STATE_PROGRESS;
 
1192
                fr.subclass = AST_CONTROL_PROGRESS;
 
1193
                local_queue_frame(i, &fr);
 
1194
        }
 
1195
        return;
 
1196
}
 
1197
 
 
1198
/*
 
1199
 * hangup a line (CAPI messages)
 
1200
 */
 
1201
static void capi_activehangup(struct ast_channel *c, int state)
 
1202
{
 
1203
        struct capi_pvt *i = CC_CHANNEL_PVT(c);
 
1204
        _cmsg CMSG;
 
1205
        const char *cause;
 
1206
 
 
1207
        i->cause = c->hangupcause;
 
1208
        if ((cause = pbx_builtin_getvar_helper(c, "PRI_CAUSE"))) {
 
1209
                i->cause = atoi(cause);
 
1210
        }
 
1211
        
 
1212
        if ((i->isdnstate & CAPI_ISDN_STATE_ECT)) {
 
1213
                cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: activehangup ECT call\n",
 
1214
                        i->vname);
 
1215
                /* we do nothing, just wait for DISCONNECT_IND */
 
1216
                return;
 
1217
        }
 
1218
 
 
1219
        cc_verbose(2, 1, VERBOSE_PREFIX_3 "%s: activehangingup (cause=%d) for PLCI=%#x\n",
 
1220
                i->vname, i->cause, i->PLCI);
 
1221
 
 
1222
 
 
1223
        if ((state == CAPI_STATE_ALERTING) ||
 
1224
            (state == CAPI_STATE_DID) || (state == CAPI_STATE_INCALL)) {
 
1225
                CONNECT_RESP_HEADER(&CMSG, capi_ApplID, i->MessageNumber, 0);
 
1226
                CONNECT_RESP_PLCI(&CMSG) = i->PLCI;
 
1227
                CONNECT_RESP_REJECT(&CMSG) = (i->cause) ? (0x3480 | (i->cause & 0x7f)) : 2;
 
1228
                _capi_put_cmsg(&CMSG);
 
1229
                return;
 
1230
        }
 
1231
 
 
1232
        /* active disconnect */
 
1233
        if ((i->isdnstate & CAPI_ISDN_STATE_B3_UP)) {
 
1234
                cc_disconnect_b3(i, 0);
 
1235
                return;
 
1236
        }
 
1237
        
 
1238
        if ((state == CAPI_STATE_CONNECTED) || (state == CAPI_STATE_CONNECTPENDING) ||
 
1239
            (state == CAPI_STATE_ANSWERING) || (state == CAPI_STATE_ONHOLD)) {
 
1240
                cc_mutex_lock(&i->lock);
 
1241
                if (i->PLCI == 0) {
 
1242
                        /* CONNECT_CONF not received yet? */
 
1243
                        capi_wait_conf(i, CAPI_CONNECT_CONF);
 
1244
                }
 
1245
                DISCONNECT_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(), 0);
 
1246
                DISCONNECT_REQ_PLCI(&CMSG) = i->PLCI;
 
1247
                _capi_put_cmsg_wait_conf(i, &CMSG);
 
1248
                cc_mutex_unlock(&i->lock);
 
1249
        }
 
1250
        return;
 
1251
}
 
1252
 
 
1253
/*
 
1254
 * PBX tells us to hangup a line
 
1255
 */
 
1256
static int pbx_capi_hangup(struct ast_channel *c)
 
1257
{
 
1258
        struct capi_pvt *i = CC_CHANNEL_PVT(c);
 
1259
        int cleanup = 0;
 
1260
        int state;
 
1261
 
 
1262
        /*
 
1263
         * hmm....ok...this is called to free the capi interface (passive disconnect)
 
1264
         * or to bring down the channel (active disconnect)
 
1265
         */
 
1266
 
 
1267
        if (i == NULL) {
 
1268
                cc_log(LOG_ERROR, "channel has no interface!\n");
 
1269
                return -1;
 
1270
        }
 
1271
 
 
1272
        cc_mutex_lock(&i->lock);
 
1273
 
 
1274
        state = i->state;
 
1275
 
 
1276
        cc_verbose(3, 0, VERBOSE_PREFIX_2 "%s: CAPI Hangingup for PLCI=%#x in state %d\n",
 
1277
                i->vname, i->PLCI, state);
 
1278
 
 
1279
        /* are we down, yet? */
 
1280
        if (state != CAPI_STATE_DISCONNECTED) {
 
1281
                /* no */
 
1282
                i->state = CAPI_STATE_DISCONNECTING;
 
1283
        } else {
 
1284
                cleanup = 1;
 
1285
        }
 
1286
        
 
1287
        ast_update_use_count();
 
1288
        
 
1289
        if ((i->doDTMF > 0) && (i->vad != NULL)) {
 
1290
                ast_dsp_free(i->vad);
 
1291
                i->vad = NULL;
 
1292
        }
 
1293
        
 
1294
        if (cleanup) {
 
1295
                /* disconnect already done, so cleanup */
 
1296
                interface_cleanup(i);
 
1297
        }
 
1298
        cc_mutex_unlock(&i->lock);
 
1299
 
 
1300
        if (!cleanup) {
 
1301
                /* not disconnected yet, we must actively do it */
 
1302
                capi_activehangup(c, state);
 
1303
        }
 
1304
 
 
1305
        CC_CHANNEL_PVT(c) = NULL;
 
1306
        ast_setstate(c, AST_STATE_DOWN);
 
1307
 
 
1308
        cc_mutex_lock(&usecnt_lock);
614
1309
        usecnt--;
615
 
    ast_mutex_unlock(&usecnt_lock);
616
 
    ast_update_use_count();
617
 
    i->mypipe = NULL;
618
 
    i = NULL;
619
 
    c->pvt->pvt = NULL;
620
 
    ast_setstate(c,AST_STATE_DOWN);
621
 
    return 0;
622
 
}
623
 
 
624
 
static char *capi_number(char *data,int strip) {
625
 
    unsigned len = *data;
626
 
    // XXX fix me
627
 
    // convert a capi struct to a \0 terminated string
628
 
    if (!len || len < (unsigned int) strip) return NULL;
629
 
    len = len - strip;
630
 
    data = (char *)(data + 1 + strip);
631
 
    return strndup((char *)data,len);
632
 
}
633
 
 
634
 
int capi_call(struct ast_channel *c, char *idest, int timeout)
635
 
{
636
 
        struct ast_capi_pvt *i;
637
 
        struct capi_pipe *p = NULL;
638
 
        int fds[2];
639
 
        char *dest,*msn;
 
1310
        cc_mutex_unlock(&usecnt_lock);
 
1311
        
 
1312
        return 0;
 
1313
}
 
1314
 
 
1315
/*
 
1316
 * convert a number
 
1317
 */
 
1318
static char *capi_number_func(unsigned char *data, unsigned int strip, char *buf)
 
1319
{
 
1320
        unsigned int len;
 
1321
 
 
1322
        if (data[0] == 0xff) {
 
1323
                len = read_capi_word(&data[1]);
 
1324
                data += 2;
 
1325
        } else {
 
1326
                len = data[0];
 
1327
                data += 1;
 
1328
        }
 
1329
        if (len > (AST_MAX_EXTENSION - 1))
 
1330
                len = (AST_MAX_EXTENSION - 1);
 
1331
        
 
1332
        /* convert a capi struct to a \0 terminated string */
 
1333
        if ((!len) || (len < strip))
 
1334
                return NULL;
 
1335
                
 
1336
        len = len - strip;
 
1337
        data += strip;
 
1338
 
 
1339
        memcpy(buf, data, len);
 
1340
        buf[len] = '\0';
 
1341
        
 
1342
        return buf;
 
1343
}
 
1344
#define capi_number(data, strip) \
 
1345
  capi_number_func(data, strip, alloca(AST_MAX_EXTENSION))
 
1346
 
 
1347
/*
 
1348
 * parse the dialstring
 
1349
 */
 
1350
static void parse_dialstring(char *buffer, char **interface, char **dest, char **param, char **ocid)
 
1351
{
 
1352
        int cp = 0;
 
1353
        char *buffer_p = buffer;
 
1354
        char *oc;
 
1355
 
 
1356
        /* interface is the first part of the string */
 
1357
        *interface = buffer;
 
1358
 
 
1359
        *dest = emptyid;
 
1360
        *param = emptyid;
 
1361
        *ocid = NULL;
 
1362
 
 
1363
        while (*buffer_p) {
 
1364
                if (*buffer_p == '/') {
 
1365
                        *buffer_p = 0;
 
1366
                        buffer_p++;
 
1367
                        if (cp == 0) {
 
1368
                                *dest = buffer_p;
 
1369
                                cp++;
 
1370
                        } else if (cp == 1) {
 
1371
                                *param = buffer_p;
 
1372
                                cp++;
 
1373
                        } else {
 
1374
                                cc_log(LOG_WARNING, "Too many parts in dialstring '%s'\n",
 
1375
                                        buffer);
 
1376
                        }
 
1377
                        continue;
 
1378
                }
 
1379
                buffer_p++;
 
1380
        }
 
1381
        if ((oc = strchr(*dest, ':')) != NULL) {
 
1382
                *ocid = *dest;
 
1383
                *oc = '\0';
 
1384
                *dest = oc + 1;
 
1385
        }
 
1386
        cc_verbose(3, 1, VERBOSE_PREFIX_4 "parsed dialstring: '%s' '%s' '%s' '%s'\n",
 
1387
                *interface, (*ocid) ? *ocid : "NULL", *dest, *param);
 
1388
        return;
 
1389
}
 
1390
 
 
1391
/*
 
1392
 * PBX tells us to make a call
 
1393
 */
 
1394
static int pbx_capi_call(struct ast_channel *c, char *idest, int timeout)
 
1395
{
 
1396
        struct capi_pvt *i = CC_CHANNEL_PVT(c);
 
1397
        char *dest, *interface, *param, *ocid;
640
1398
        char buffer[AST_MAX_EXTENSION];
641
 
        char called[AST_MAX_EXTENSION],calling[AST_MAX_EXTENSION];
 
1399
        char called[AST_MAX_EXTENSION], calling[AST_MAX_EXTENSION];
 
1400
        char callerid[AST_MAX_EXTENSION];
642
1401
        char bchaninfo[3];
 
1402
        int CLIR;
 
1403
        int callernplan = 0;
 
1404
        int use_defaultcid = 0;
 
1405
        const char *ton, *p;
 
1406
        char *osa = NULL;
 
1407
        char *dsa = NULL;
 
1408
        char callingsubaddress[AST_MAX_EXTENSION];
 
1409
        char calledsubaddress[AST_MAX_EXTENSION];
643
1410
        
644
1411
        _cmsg CMSG;
645
1412
        MESSAGE_EXCHANGE_ERROR  error;
646
 
        
647
 
        strncpy(buffer,(char *)idest,sizeof(buffer)-1);
648
 
        msn = strtok(buffer, ":");
649
 
        dest = strtok(NULL, ":");
650
 
 
651
 
 
652
 
        if (!dest) {
653
 
                ast_log(LOG_WARNING, "Destination %s requres a real destination\n", idest);
 
1413
 
 
1414
        cc_copy_string(buffer, idest, sizeof(buffer));
 
1415
        parse_dialstring(buffer, &interface, &dest, &param, &ocid);
 
1416
 
 
1417
        /* init param settings */
 
1418
        i->doB3 = CAPI_B3_DONT;
 
1419
        i->doOverlap = 0;
 
1420
        memset(i->overlapdigits, 0, sizeof(i->overlapdigits));
 
1421
 
 
1422
        /* parse the parameters */
 
1423
        while ((param) && (*param)) {
 
1424
                switch (*param) {
 
1425
                case 'b':       /* always B3 */
 
1426
                        if (i->doB3 != CAPI_B3_DONT)
 
1427
                                cc_log(LOG_WARNING, "B3 already set in '%s'\n", idest);
 
1428
                        i->doB3 = CAPI_B3_ALWAYS;
 
1429
                        break;
 
1430
                case 'B':       /* only do B3 on successfull calls */
 
1431
                        if (i->doB3 != CAPI_B3_DONT)
 
1432
                                cc_log(LOG_WARNING, "B3 already set in '%s'\n", idest);
 
1433
                        i->doB3 = CAPI_B3_ON_SUCCESS;
 
1434
                        break;
 
1435
                case 'o':       /* overlap sending of digits */
 
1436
                        if (i->doOverlap)
 
1437
                                cc_log(LOG_WARNING, "Overlap already set in '%s'\n", idest);
 
1438
                        i->doOverlap = 1;
 
1439
                        break;
 
1440
                case 'd':       /* use default cid */
 
1441
                        if (use_defaultcid)
 
1442
                                cc_log(LOG_WARNING, "Default CID already set in '%s'\n", idest);
 
1443
                        use_defaultcid = 1;
 
1444
                        break;
 
1445
                default:
 
1446
                        cc_log(LOG_WARNING, "Unknown parameter '%c' in '%s', ignoring.\n",
 
1447
                                *param, idest);
 
1448
                }
 
1449
                param++;
 
1450
        }
 
1451
        if (((!dest) || (!dest[0])) && (i->doB3 != CAPI_B3_ALWAYS)) {
 
1452
                cc_log(LOG_ERROR, "No destination or dialtone requested in '%s'\n", idest);
654
1453
                return -1;
655
1454
        }
656
 
        i = c->pvt->pvt;
657
 
        i->doB3 = AST_CAPI_B3_DONT; // <homer>DOH</homer>
658
 
 
659
 
        // always B3
660
 
        if (((char *)dest)[0] == 'b') {
661
 
            i->doB3 = AST_CAPI_B3_ALWAYS;
662
 
        }
663
 
        // only do B3 on successfull calls
664
 
        if (((char *)dest)[0] == 'B') {
665
 
            i->doB3 = AST_CAPI_B3_ON_SUCCESS;
666
 
        } 
667
 
        
668
 
        if (i->doB3 != AST_CAPI_B3_DONT) {
669
 
            dest++;
670
 
        }
671
 
 
672
 
        if (option_verbose > 1) {
673
 
            if (capidebug)
674
 
                ast_verbose(VERBOSE_PREFIX_2 "CAPI Call %s %s", c->name, i->doB3?"with B3":"");
675
 
        }
676
 
    
677
 
        if (((char *)msn)[0] == '@') {
678
 
            i->CLIR = 1;
679
 
            msn++;
680
 
        } else {
681
 
            i->CLIR = 0;
682
 
        }
683
 
 
684
 
        if (pipe(fds) == 0) {
685
 
            ast_mutex_lock(&pipelock);
686
 
            i->fd = fds[0];
687
 
            p = malloc(sizeof(struct capi_pipe));
688
 
            memset(p, 0, sizeof(struct capi_pipe));
689
 
            p->fd = fds[1];
690
 
            c->fds[0] = fds[1];
691
 
            p->PLCI = -1;
692
 
            p->i = i;
693
 
            p->c = c;
694
 
            i->mypipe = p;
695
 
            p->next = pipelist;
696
 
            pipelist = p;
697
 
            if (option_verbose > 4) {
698
 
                ast_verbose(VERBOSE_PREFIX_3 "creating pipe for PLCI=-1\n");
699
 
            }
700
 
            ast_mutex_unlock(&pipelock);
701
 
        }
702
 
        i->outgoing = 1;
703
 
        
704
 
        i->MessageNumber = ast_capi_MessageNumber++;
705
 
        CONNECT_REQ_HEADER(&CMSG, ast_capi_ApplID, i->MessageNumber, i->controller);
 
1455
 
 
1456
        CLIR = c->cid.cid_pres;
 
1457
        callernplan = c->cid.cid_ton & 0x7f;
 
1458
 
 
1459
        if ((ton = pbx_builtin_getvar_helper(c, "CALLERTON"))) {
 
1460
                callernplan = atoi(ton) & 0x7f;
 
1461
        }
 
1462
        cc_verbose(1, 1, VERBOSE_PREFIX_2 "%s: Call %s %s%s (pres=0x%02x, ton=0x%02x)\n",
 
1463
                i->vname, c->name, i->doB3 ? "with B3 ":" ",
 
1464
                i->doOverlap ? "overlap":"", CLIR, callernplan);
 
1465
 
 
1466
        if ((p = pbx_builtin_getvar_helper(c, "CALLINGSUBADDRESS"))) {
 
1467
                callingsubaddress[0] = strlen(p) + 1;
 
1468
                callingsubaddress[1] = 0x80;
 
1469
                strncpy(&callingsubaddress[2], p, sizeof(callingsubaddress) - 3);
 
1470
                osa = callingsubaddress;
 
1471
        }
 
1472
        if ((p = pbx_builtin_getvar_helper(c, "CALLEDSUBADDRESS"))) {
 
1473
                calledsubaddress[0] = strlen(p) + 1;
 
1474
                calledsubaddress[1] = 0x80;
 
1475
                strncpy(&calledsubaddress[2], p, sizeof(calledsubaddress) - 3);
 
1476
                dsa = calledsubaddress;
 
1477
        }
 
1478
 
 
1479
        i->MessageNumber = get_capi_MessageNumber();
 
1480
        CONNECT_REQ_HEADER(&CMSG, capi_ApplID, i->MessageNumber, i->controller);
706
1481
        CONNECT_REQ_CONTROLLER(&CMSG) = i->controller;
707
 
        CONNECT_REQ_CIPVALUE(&CMSG) = 0x10;     // Telephony, could also use 0x04 (3.1Khz audio)
708
 
        called[0] = strlen(dest)+1;
 
1482
        CONNECT_REQ_CIPVALUE(&CMSG) = tcap2cip(c->transfercapability);
 
1483
        if (tcap_is_digital(c->transfercapability)) {
 
1484
                i->bproto = CC_BPROTO_TRANSPARENT;
 
1485
                cc_verbose(4, 0, VERBOSE_PREFIX_2 "%s: is digital call, set proto to TRANSPARENT\n",
 
1486
                        i->vname);
 
1487
        }
 
1488
        if ((i->doOverlap) && (strlen(dest))) {
 
1489
                cc_copy_string(i->overlapdigits, dest, sizeof(i->overlapdigits));
 
1490
                called[0] = 1;
 
1491
        } else {
 
1492
                i->doOverlap = 0;
 
1493
                called[0] = strlen(dest) + 1;
 
1494
        }
709
1495
        called[1] = 0x80;
710
 
        strncpy(&called[2],dest,sizeof(called)-2);
711
 
        CONNECT_REQ_CALLEDPARTYNUMBER(&CMSG) = called;
712
 
        CONNECT_REQ_CALLEDPARTYSUBADDRESS(&CMSG) = NULL;
713
 
 
714
 
        if (i->isdnmode && (strlen(msn)>strlen(i->msn)) && !strncmp(msn, i->msn, strlen(i->msn)))
715
 
            msn += strlen(i->msn);
716
 
 
717
 
        calling[0] = strlen(msn)+2;
718
 
        calling[1] = 0x0;
719
 
        if (i->CLIR == 1) {
720
 
            calling[2] = 0xA0; // CLIR
 
1496
        strncpy(&called[2], dest, sizeof(called) - 3);
 
1497
        CONNECT_REQ_CALLEDPARTYNUMBER(&CMSG) = (_cstruct)called;
 
1498
        CONNECT_REQ_CALLEDPARTYSUBADDRESS(&CMSG) = (_cstruct)dsa;
 
1499
 
 
1500
        if (c->cid.cid_num) {
 
1501
                cc_copy_string(callerid, c->cid.cid_num, sizeof(callerid));
721
1502
        } else {
722
 
            calling[2] = 0x80; // CLIP
723
 
        }
724
 
        strncpy(&calling[3],msn,sizeof(calling)-3);
725
 
        CONNECT_REQ_CALLINGPARTYNUMBER(&CMSG) = calling;
726
 
        CONNECT_REQ_CALLINGPARTYSUBADDRESS(&CMSG) = NULL;
727
 
 
728
 
        CONNECT_REQ_B1PROTOCOL(&CMSG) = 1;
729
 
        CONNECT_REQ_B2PROTOCOL(&CMSG) = 1; // 1
730
 
        CONNECT_REQ_B3PROTOCOL(&CMSG) = 0;
 
1503
                memset(callerid, 0, sizeof(callerid));
 
1504
        }
 
1505
 
 
1506
        if (use_defaultcid) {
 
1507
                cc_copy_string(callerid, i->defaultcid, sizeof(callerid));
 
1508
        } else if (ocid) {
 
1509
                cc_copy_string(callerid, ocid, sizeof(callerid));
 
1510
        }
 
1511
        cc_copy_string(i->cid, callerid, sizeof(i->cid));
 
1512
 
 
1513
        calling[0] = strlen(callerid) + 2;
 
1514
        calling[1] = callernplan;
 
1515
        calling[2] = 0x80 | (CLIR & 0x63);
 
1516
        strncpy(&calling[3], callerid, sizeof(calling) - 4);
 
1517
 
 
1518
        CONNECT_REQ_CALLINGPARTYNUMBER(&CMSG) = (_cstruct)calling;
 
1519
        CONNECT_REQ_CALLINGPARTYSUBADDRESS(&CMSG) = (_cstruct)osa;
 
1520
 
 
1521
        CONNECT_REQ_B1PROTOCOL(&CMSG) = b_protocol_table[i->bproto].b1protocol;
 
1522
        CONNECT_REQ_B2PROTOCOL(&CMSG) = b_protocol_table[i->bproto].b2protocol;
 
1523
        CONNECT_REQ_B3PROTOCOL(&CMSG) = b_protocol_table[i->bproto].b3protocol;
 
1524
        CONNECT_REQ_B1CONFIGURATION(&CMSG) = b_protocol_table[i->bproto].b1configuration;
 
1525
        CONNECT_REQ_B2CONFIGURATION(&CMSG) = b_protocol_table[i->bproto].b2configuration;
 
1526
        CONNECT_REQ_B3CONFIGURATION(&CMSG) = b_protocol_table[i->bproto].b3configuration;
731
1527
 
732
1528
        bchaninfo[0] = 2;
733
1529
        bchaninfo[1] = 0x0;
734
1530
        bchaninfo[2] = 0x0;
735
 
        CONNECT_REQ_BCHANNELINFORMATION(&CMSG) = bchaninfo; // 0
736
 
 
737
 
        if ((error = _capi_put_cmsg(&CMSG))) {
738
 
            ast_log(LOG_ERROR,"error sending CONNECT_REQ (error=%#x)\n",error);
739
 
            return error;
740
 
        } else {
741
 
            if (option_verbose > 5) {
742
 
                ast_verbose(VERBOSE_PREFIX_4 "sent CONNECT_REQ MN =%#x\n",CMSG.Messagenumber);
743
 
            }
744
 
        }
745
 
 
 
1531
        CONNECT_REQ_BCHANNELINFORMATION(&CMSG) = (_cstruct)bchaninfo; /* 0 */
 
1532
 
 
1533
        cc_mutex_lock(&i->lock);
 
1534
 
 
1535
        i->outgoing = 1;
 
1536
        i->isdnstate |= CAPI_ISDN_STATE_PBX;
746
1537
        i->state = CAPI_STATE_CONNECTPENDING;
747
 
 
748
1538
        ast_setstate(c, AST_STATE_DIALING);
749
1539
 
750
 
        // XXX fixme, not nice:
751
 
/*      if (i->controller > 0) {
752
 
            capi_controllers[i->controller]->nfreebchannels--;
753
 
        } */
754
 
 
755
 
        // now we shall return .... the rest has to be done by handle_msg
756
 
    return 0;
757
 
}
758
 
 
759
 
 
760
 
static int capi_answer(struct ast_channel *c) {
761
 
    struct ast_capi_pvt *i = c->pvt->pvt;
762
 
    MESSAGE_EXCHANGE_ERROR  error;
763
 
    _cmsg                   CMSG;
764
 
    char buf[AST_MAX_EXTENSION];
765
 
    char *dnid;
766
 
    
767
 
    if (i->isdnmode && (strlen(i->incomingmsn)<strlen(i->dnid)))
768
 
        dnid = i->dnid + strlen(i->incomingmsn);
769
 
    else
770
 
        dnid = i->dnid;
771
 
 
772
 
    CONNECT_RESP_HEADER(&CMSG, ast_capi_ApplID, i->MessageNumber, 0);
773
 
    CONNECT_RESP_PLCI(&CMSG) = i->PLCI;
774
 
    CONNECT_RESP_REJECT(&CMSG) = 0;
775
 
    buf[0] = strlen(dnid)+2;
776
 
    buf[1] = 0x0;
777
 
    buf[2] = 0x80;
778
 
    strncpy(&buf[3],dnid,sizeof(buf)-4);
779
 
    CONNECT_RESP_CONNECTEDNUMBER(&CMSG) = buf;
780
 
    CONNECT_RESP_CONNECTEDSUBADDRESS(&CMSG) = NULL;
781
 
    CONNECT_RESP_LLC(&CMSG) = NULL;
782
 
    CONNECT_RESP_B1PROTOCOL(&CMSG) = 1;
783
 
    CONNECT_RESP_B2PROTOCOL(&CMSG) = 1;
784
 
    CONNECT_RESP_B3PROTOCOL(&CMSG) = 0;
785
 
 
786
 
    if (option_verbose > 3)
787
 
        ast_verbose(VERBOSE_PREFIX_3 "CAPI Answering for MSN %s\n", dnid);
788
 
    if ((error = _capi_put_cmsg(&CMSG)) != 0) {
789
 
        return -1;      
790
 
    } else {
791
 
        if (option_verbose > 5) {
792
 
            if (capidebug) 
793
 
                ast_verbose(VERBOSE_PREFIX_4 "sent CONNECT_RESP PLCI = %#x DNID = %s\n",i->PLCI,i->dnid);
794
 
        }
795
 
    }
796
 
    
797
 
    i->state = CAPI_STATE_ANSWERING;
798
 
    i->doB3 = AST_CAPI_B3_DONT;
799
 
    i->outgoing = 0;
800
 
    i->earlyB3 = -1;
801
 
 
802
 
    return 0;
803
 
}
804
 
 
805
 
struct ast_frame *capi_read(struct ast_channel *c) 
806
 
{
807
 
        struct ast_capi_pvt *i = c->pvt->pvt;
808
 
        int readsize = 0;
809
 
 
810
 
        if ((i->state == CAPI_STATE_REMOTE_HANGUP)) {
811
 
            ast_log(LOG_ERROR,"this channel is not connected\n");
812
 
            return NULL;
813
 
        }
814
 
        if (i->state == CAPI_STATE_ONHOLD) {
815
 
            i->fr.frametype = AST_FRAME_NULL;
816
 
            return &i->fr;
817
 
        }
818
 
        
 
1540
        if ((error = _capi_put_cmsg(&CMSG))) {
 
1541
                i->state = CAPI_STATE_DISCONNECTED;
 
1542
                ast_setstate(c, AST_STATE_RESERVED);
 
1543
                cc_mutex_unlock(&i->lock);
 
1544
                return error;
 
1545
        }
 
1546
        cc_mutex_unlock(&i->lock);
 
1547
 
 
1548
        /* now we shall return .... the rest has to be done by handle_msg */
 
1549
        return 0;
 
1550
}
 
1551
 
 
1552
/*
 
1553
 * answer a capi call
 
1554
 */
 
1555
static int capi_send_answer(struct ast_channel *c, _cstruct b3conf)
 
1556
{
 
1557
        struct capi_pvt *i = CC_CHANNEL_PVT(c);
 
1558
        _cmsg CMSG;
 
1559
        char buf[CAPI_MAX_STRING];
 
1560
        const char *dnid;
 
1561
        const char *connectednumber;
 
1562
    
 
1563
        if ((i->isdnmode == CAPI_ISDNMODE_DID) &&
 
1564
            ((strlen(i->incomingmsn) < strlen(i->dnid)) && 
 
1565
            (strcmp(i->incomingmsn, "*")))) {
 
1566
                dnid = i->dnid + strlen(i->incomingmsn);
 
1567
        } else {
 
1568
                dnid = i->dnid;
 
1569
        }
 
1570
        if ((connectednumber = pbx_builtin_getvar_helper(c, "CONNECTEDNUMBER"))) {
 
1571
                dnid = connectednumber;
 
1572
        }
 
1573
 
 
1574
        CONNECT_RESP_HEADER(&CMSG, capi_ApplID, i->MessageNumber, 0);
 
1575
        CONNECT_RESP_PLCI(&CMSG) = i->PLCI;
 
1576
        CONNECT_RESP_REJECT(&CMSG) = 0;
 
1577
        if (strlen(dnid)) {
 
1578
                buf[0] = strlen(dnid) + 2;
 
1579
                buf[1] = 0x00;
 
1580
                buf[2] = 0x80;
 
1581
                strncpy(&buf[3], dnid, sizeof(buf) - 4);
 
1582
                CONNECT_RESP_CONNECTEDNUMBER(&CMSG) = (_cstruct)buf;
 
1583
        }
 
1584
        CONNECT_RESP_B1PROTOCOL(&CMSG) = b_protocol_table[i->bproto].b1protocol;
 
1585
        CONNECT_RESP_B2PROTOCOL(&CMSG) = b_protocol_table[i->bproto].b2protocol;
 
1586
        CONNECT_RESP_B3PROTOCOL(&CMSG) = b_protocol_table[i->bproto].b3protocol;
 
1587
        CONNECT_RESP_B1CONFIGURATION(&CMSG) = b_protocol_table[i->bproto].b1configuration;
 
1588
        CONNECT_RESP_B2CONFIGURATION(&CMSG) = b_protocol_table[i->bproto].b2configuration;
 
1589
        if (!b3conf)
 
1590
                b3conf = b_protocol_table[i->bproto].b3configuration;
 
1591
        CONNECT_RESP_B3CONFIGURATION(&CMSG) = b3conf;
 
1592
#ifndef CC_HAVE_NO_GLOBALCONFIGURATION
 
1593
        CONNECT_RESP_GLOBALCONFIGURATION(&CMSG) = capi_set_global_configuration(i);
 
1594
#endif
 
1595
 
 
1596
        cc_verbose(3, 0, VERBOSE_PREFIX_2 "%s: Answering for %s\n",
 
1597
                i->vname, dnid);
 
1598
                
 
1599
        if (_capi_put_cmsg(&CMSG) != 0) {
 
1600
                return -1;      
 
1601
        }
 
1602
    
 
1603
        i->state = CAPI_STATE_ANSWERING;
 
1604
        i->doB3 = CAPI_B3_DONT;
 
1605
        i->outgoing = 0;
 
1606
 
 
1607
        return 0;
 
1608
}
 
1609
 
 
1610
/*
 
1611
 * PBX tells us to answer a call
 
1612
 */
 
1613
static int pbx_capi_answer(struct ast_channel *c)
 
1614
{
 
1615
        struct capi_pvt *i = CC_CHANNEL_PVT(c);
 
1616
        int ret;
 
1617
 
 
1618
        i->bproto = CC_BPROTO_TRANSPARENT;
 
1619
 
 
1620
        if (i->rtp) {
 
1621
                if (!tcap_is_digital(c->transfercapability))
 
1622
                        i->bproto = CC_BPROTO_RTP;
 
1623
        }
 
1624
 
 
1625
        ret = capi_send_answer(c, NULL);
 
1626
        return ret;
 
1627
}
 
1628
 
 
1629
/*
 
1630
 * read for a channel
 
1631
 */
 
1632
static struct ast_frame *pbx_capi_read(struct ast_channel *c) 
 
1633
{
 
1634
        struct capi_pvt *i = CC_CHANNEL_PVT(c);
 
1635
        struct ast_frame *f;
 
1636
        int readsize;
 
1637
 
819
1638
        if (i == NULL) {
820
 
            ast_log(LOG_ERROR,"channel has no interface\n");
821
 
            return NULL;
822
 
        }
823
 
        i->fr.frametype = AST_FRAME_NULL;
824
 
        i->fr.subclass = 0;
825
 
#ifdef UNSTABLE_CVS
826
 
        i->fr.delivery.tv_sec = 0;
827
 
        i->fr.delivery.tv_usec = 0;
828
 
#endif  
829
 
        readsize = read(i->fd,&i->fr,sizeof(struct ast_frame));
 
1639
                cc_log(LOG_ERROR, "channel has no interface\n");
 
1640
                return NULL;
 
1641
        }
 
1642
        if (i->readerfd == -1) {
 
1643
                cc_log(LOG_ERROR, "no readerfd\n");
 
1644
                return NULL;
 
1645
        }
 
1646
 
 
1647
        f = &i->f;
 
1648
        f->frametype = AST_FRAME_NULL;
 
1649
        f->subclass = 0;
 
1650
 
 
1651
        readsize = read(i->readerfd, f, sizeof(struct ast_frame));
830
1652
        if (readsize != sizeof(struct ast_frame)) {
831
 
            ast_log(LOG_ERROR,"did not read a whole frame\n");
832
 
        }
833
 
        if (i->fr.frametype == AST_FRAME_VOICE) {
834
 
            readsize = read(i->fd,i->fr.data,i->fr.datalen);
835
 
            if (readsize != i->fr.datalen) {
836
 
                ast_log(LOG_ERROR,"did not read whole frame data\n");
837
 
            }
838
 
        }
839
 
        i->fr.mallocd = 0;      
840
 
        if (i->fr.frametype == AST_FRAME_NULL) {
841
 
            return NULL;
842
 
        }
843
 
        return &i->fr;
 
1653
                cc_log(LOG_ERROR, "did not read a whole frame\n");
 
1654
        }
 
1655
        
 
1656
        f->mallocd = 0;
 
1657
        f->data = NULL;
 
1658
 
 
1659
        if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP)) {
 
1660
                return NULL;
 
1661
        }
 
1662
 
 
1663
        if ((f->frametype == AST_FRAME_VOICE) && (f->datalen > 0)) {
 
1664
                if (f->datalen > sizeof(i->frame_data)) {
 
1665
                        cc_log(LOG_ERROR, "f.datalen(%d) greater than space of frame_data(%d)\n",
 
1666
                                f->datalen, sizeof(i->frame_data));
 
1667
                        f->datalen = sizeof(i->frame_data);
 
1668
                }
 
1669
                readsize = read(i->readerfd, i->frame_data + AST_FRIENDLY_OFFSET, f->datalen);
 
1670
                if (readsize != f->datalen) {
 
1671
                        cc_log(LOG_ERROR, "did not read whole frame data\n");
 
1672
                }
 
1673
                f->data = i->frame_data + AST_FRIENDLY_OFFSET;
 
1674
                if ((i->doDTMF > 0) && (i->vad != NULL) ) {
 
1675
                        f = ast_dsp_process(c, i->vad, f);
 
1676
                }
 
1677
        }
 
1678
        return f;
844
1679
}
845
1680
 
846
 
int capi_write(struct ast_channel *c, struct ast_frame *f)
 
1681
/*
 
1682
 * PBX tells us to write for a channel
 
1683
 */
 
1684
static int pbx_capi_write(struct ast_channel *c, struct ast_frame *f)
847
1685
{
848
 
        struct ast_capi_pvt *i = c->pvt->pvt;
 
1686
        struct capi_pvt *i = CC_CHANNEL_PVT(c);
 
1687
        MESSAGE_EXCHANGE_ERROR error;
849
1688
        _cmsg CMSG;
850
 
        MESSAGE_EXCHANGE_ERROR  error;
851
 
        int j=0;
852
 
        char buf[1000];
 
1689
        int j = 0;
 
1690
        unsigned char *buf;
853
1691
        struct ast_frame *fsmooth;
854
 
#ifdef CAPI_ES
855
1692
        int txavg=0;
856
 
#endif
857
 
 
858
 
#ifndef NEVER_EVER_EARLY_B3_CONNECTS
859
 
        // dont send audio to the local exchange!
860
 
        if (i->earlyB3 == 1 || !i->NCCI) {
861
 
            return 0;
862
 
        }
863
 
#endif
 
1693
        int ret = 0;
864
1694
 
865
1695
        if (!i) {
866
 
            ast_log(LOG_ERROR,"channel has no interface\n");
867
 
            return -1;
868
 
        } 
 
1696
                cc_log(LOG_ERROR, "channel has no interface\n");
 
1697
                return -1;
 
1698
        }
 
1699
         
 
1700
        if ((!(i->isdnstate & CAPI_ISDN_STATE_B3_UP)) || (!i->NCCI) ||
 
1701
            ((i->isdnstate & (CAPI_ISDN_STATE_B3_CHANGE | CAPI_ISDN_STATE_LI)))) {
 
1702
                return 0;
 
1703
        }
 
1704
 
 
1705
        if ((!(i->ntmode)) && (i->state != CAPI_STATE_CONNECTED)) {
 
1706
                return 0;
 
1707
        }
869
1708
 
870
1709
        if (f->frametype == AST_FRAME_NULL) {
871
 
            return 0;
 
1710
                return 0;
872
1711
        }
873
1712
        if (f->frametype == AST_FRAME_DTMF) {
874
 
            ast_log(LOG_ERROR,"dtmf frame should be written\n");
875
 
            return 0;
 
1713
                cc_log(LOG_ERROR, "dtmf frame should be written\n");
 
1714
                return 0;
876
1715
        }
877
1716
        if (f->frametype != AST_FRAME_VOICE) {
878
 
            ast_log(LOG_ERROR,"not a voice frame\n");
879
 
            return -1;
880
 
        }
881
 
        if (f->subclass != capi_capability) {
882
 
            ast_log(LOG_ERROR,"dont know how to write subclass %d\n",f->subclass);
883
 
            return -1;
884
 
        }
885
 
//      ast_log(LOG_NOTICE,"writing frame %d %d\n",f->frametype,f->subclass);
886
 
 
887
 
    if (ast_smoother_feed(i->smoother, f)!=0) {
888
 
        ast_log(LOG_ERROR,"failed to fill smoother\n");
889
 
        return -1;
890
 
    }
891
 
 
892
 
    fsmooth=ast_smoother_read(i->smoother);
893
 
    while(fsmooth != NULL) {
894
 
        DATA_B3_REQ_HEADER(&CMSG, ast_capi_ApplID, ast_capi_MessageNumber++, 0);
895
 
        DATA_B3_REQ_NCCI(&CMSG) = i->NCCI;
896
 
        DATA_B3_REQ_DATALENGTH(&CMSG) = fsmooth->datalen;
897
 
        DATA_B3_REQ_FLAGS(&CMSG) = 0; 
898
 
 
899
 
        if (ast_mutex_lock(&capi_send_buffer_lock)) {
900
 
            ast_log(LOG_WARNING,"Unable to lock B3 send buffer!\n");
901
 
            return -1;
902
 
        }
903
 
#ifndef CAPI_ES
904
 
#ifdef CAPI_GAIN
905
 
        for (j=0;j<fsmooth->datalen;j++) {
906
 
            buf[j] = i->g.txgains[reversebits[((unsigned char *)fsmooth->data)[j]]]; 
907
 
        }
908
 
#else
909
 
        for (j=0;j<fsmooth->datalen;j++) {
910
 
            buf[j] = reversebits[ ((unsigned char *)fsmooth->data)[j] ]; 
911
 
        }
912
 
#endif
913
 
#else
914
 
        if ((i->doES == 1)) {
915
 
            for (j=0;j<fsmooth->datalen;j++) {
916
 
                buf[j] = reversebits[ ((unsigned char *)fsmooth->data)[j] ]; 
917
 
                txavg += abs( capiXLAW2INT(reversebits[ ((unsigned char*)fsmooth->data)[j]]) );
918
 
            }
919
 
            txavg = txavg/j;
920
 
            for(j=0;j<ECHO_TX_COUNT-1;j++) {
921
 
                i->txavg[j] = i->txavg[j+1];
922
 
            }
923
 
            i->txavg[ECHO_TX_COUNT-1] = txavg;
924
 
            
925
 
//          ast_log(LOG_NOTICE,"txavg = %d\n",txavg);
926
 
        } else {
927
 
#ifdef CAPI_GAIN
928
 
            for (j=0;j<fsmooth->datalen;j++) {
929
 
                buf[j] = i->g.txgains[reversebits[((unsigned char *)fsmooth->data)[j]]]; 
930
 
            }
931
 
#else
932
 
            for (j=0;j<fsmooth->datalen;j++) {
933
 
                buf[j] = reversebits[ ((unsigned char *)fsmooth->data)[j] ]; 
934
 
            }
935
 
#endif
936
 
        }
937
 
#endif
938
 
    
939
 
        DATA_B3_REQ_DATAHANDLE(&CMSG) = capi_send_buffer_handle;
940
 
        memcpy((char *)&capi_send_buffer[(capi_send_buffer_handle % AST_CAPI_MAX_B3_BLOCKS) * AST_CAPI_MAX_B3_BLOCK_SIZE],&buf,fsmooth->datalen);
941
 
        DATA_B3_REQ_DATA(&CMSG) = (unsigned char *)&capi_send_buffer[(capi_send_buffer_handle % AST_CAPI_MAX_B3_BLOCKS) * AST_CAPI_MAX_B3_BLOCK_SIZE];
942
 
        capi_send_buffer_handle++;
943
 
    
944
 
        if (ast_mutex_unlock(&capi_send_buffer_lock)) {
945
 
            ast_log(LOG_WARNING,"Unable to unlock B3 send buffer!\n");
946
 
            return -1;
947
 
        }
948
 
 
949
 
 
950
 
#ifdef CAPI_SYNC    
951
 
    ast_mutex_lock(&i->lockB3in);
952
 
    if ((i->B3in >= 1) && (i->B3in <= AST_CAPI_MAX_B3_BLOCKS)) {
953
 
        ast_mutex_unlock(&i->lockB3in);
954
 
        if ((error = _capi_put_cmsg(&CMSG)) != 0) {
955
 
            ast_log(LOG_ERROR,"error sending DATA_B3_REQ (error=%#x, datalen=%d) B3in=%d\n",error,fsmooth->datalen,i->B3in);
956
 
//      ast_log(LOG_NOTICE,"f: timelen %d b = %d MN = %d \n",fsmooth->timelen,b,CMSG.Messagenumber);
957
 
        } else {
958
 
            if (option_verbose > 5) {
959
 
                if (capidebug) 
960
 
                    ast_verbose(VERBOSE_PREFIX_4 "sent DATA_B3_REQ (NCCI=%#x) (%d bytes)\n",i->NCCI,fsmooth->datalen);
961
 
            }
962
 
        }
963
 
        i->B3in--;
964
 
    } else {
965
 
        if (i->B3in > 0) i->B3in--;
966
 
        ast_mutex_unlock(&i->lockB3in);
967
 
    }
968
 
#else
969
 
        if ((error = _capi_put_cmsg(&CMSG)) != 0) {
970
 
            ast_log(LOG_ERROR,"error sending DATA_B3_REQ (error=%#x, datalen=%d)\n",error,fsmooth->datalen);
971
 
//      ast_log(LOG_NOTICE,"f: timelen %d b = %d MN = %d \n",fsmooth->timelen,b,CMSG.Messagenumber);
972
 
        } else {
973
 
            if (option_verbose > 5) {
974
 
                if (capidebug) 
975
 
                    ast_verbose(VERBOSE_PREFIX_4 "sent DATA_B3_REQ (NCCI=%#x) (%d bytes)\n",i->NCCI,fsmooth->datalen);
976
 
            }
977
 
        }
978
 
#endif
979
 
    
980
 
//      ast_frfree(fsmooth);
981
 
 
982
 
        fsmooth=ast_smoother_read(i->smoother);
983
 
    }
984
 
        return 0;
985
 
}
986
 
 
987
 
static int capi_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
988
 
{
989
 
        struct ast_capi_pvt *p = newchan->pvt->pvt;
990
 
        p->owner = newchan;
991
 
        return 0;
992
 
}
993
 
 
994
 
int capi_indicate(struct ast_channel *c,int condition) {
995
 
    return -1;
996
 
}
997
 
 
998
 
int capi_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc) {
999
 
    return -1;
1000
 
}
1001
 
 
1002
 
 
1003
 
struct ast_channel *capi_new(struct ast_capi_pvt *i,int state) {
1004
 
    struct ast_channel *tmp;
1005
 
    int fmt;
1006
 
 
1007
 
    tmp = ast_channel_alloc(1);
1008
 
    if (tmp != NULL) {
1009
 
//      ast_log(LOG_NOTICE,"allocated channel for PLCI=%#x!\n",i->PLCI);
1010
 
        snprintf(tmp->name,sizeof(tmp->name),"CAPI[contr%d/%s]/%d",i->controller,i->dnid,capi_counter++);
1011
 
        tmp->type = type;
1012
 
        tmp->nativeformats = capi_capability;
1013
 
        ast_setstate(tmp,state);
1014
 
        tmp->fds[0] = i->fd;
1015
 
        i->smoother = ast_smoother_new(AST_CAPI_MAX_B3_BLOCK_SIZE);
1016
 
        if (i->smoother == NULL) {
1017
 
            ast_log(LOG_ERROR, "smoother NULL!\n");
1018
 
        }
1019
 
        i->fr.frametype = 0;
1020
 
        i->fr.subclass = 0;
1021
 
#ifdef UNSTABLE_CVS
1022
 
        i->fr.delivery.tv_sec = 0;
1023
 
        i->fr.delivery.tv_usec = 0;
1024
 
#endif
 
1717
                cc_log(LOG_ERROR,"not a voice frame\n");
 
1718
                return 0;
 
1719
        }
 
1720
        if (i->FaxState & CAPI_FAX_STATE_ACTIVE) {
 
1721
                cc_verbose(3, 1, VERBOSE_PREFIX_2 "%s: write on fax activity?\n",
 
1722
                        i->vname);
 
1723
                return 0;
 
1724
        }
 
1725
        if ((!f->data) || (!f->datalen)) {
 
1726
                cc_log(LOG_DEBUG, "No data for FRAME_VOICE %s\n", c->name);
 
1727
                return 0;
 
1728
        }
 
1729
        if (i->isdnstate & CAPI_ISDN_STATE_RTP) {
 
1730
                if ((!(f->subclass & i->codec)) &&
 
1731
                    (f->subclass != capi_capability)) {
 
1732
                        cc_log(LOG_ERROR, "don't know how to write subclass %s(%d)\n",
 
1733
                                ast_getformatname(f->subclass), f->subclass);
 
1734
                        return 0;
 
1735
                }
 
1736
                return capi_write_rtp(c, f);
 
1737
        }
 
1738
 
 
1739
        if ((!i->smoother) || (ast_smoother_feed(i->smoother, f) != 0)) {
 
1740
                cc_log(LOG_ERROR, "%s: failed to fill smoother\n", i->vname);
 
1741
                return 0;
 
1742
        }
 
1743
 
 
1744
        for (fsmooth = ast_smoother_read(i->smoother);
 
1745
             fsmooth != NULL;
 
1746
             fsmooth = ast_smoother_read(i->smoother)) {
 
1747
                DATA_B3_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(), 0);
 
1748
                DATA_B3_REQ_NCCI(&CMSG) = i->NCCI;
 
1749
                DATA_B3_REQ_DATALENGTH(&CMSG) = fsmooth->datalen;
 
1750
                DATA_B3_REQ_FLAGS(&CMSG) = 0; 
 
1751
 
 
1752
                DATA_B3_REQ_DATAHANDLE(&CMSG) = i->send_buffer_handle;
 
1753
                buf = &(i->send_buffer[(i->send_buffer_handle % CAPI_MAX_B3_BLOCKS) *
 
1754
                        (CAPI_MAX_B3_BLOCK_SIZE + AST_FRIENDLY_OFFSET)]);
 
1755
                DATA_B3_REQ_DATA(&CMSG) = buf;
 
1756
                i->send_buffer_handle++;
 
1757
 
 
1758
                if ((i->doES == 1) && (!tcap_is_digital(c->transfercapability))) {
 
1759
                        for (j = 0; j < fsmooth->datalen; j++) {
 
1760
                                buf[j] = reversebits[ ((unsigned char *)fsmooth->data)[j] ]; 
 
1761
                                if (capi_capability == AST_FORMAT_ULAW) {
 
1762
                                        txavg += abs( capiULAW2INT[reversebits[ ((unsigned char*)fsmooth->data)[j]]] );
 
1763
                                } else {
 
1764
                                        txavg += abs( capiALAW2INT[reversebits[ ((unsigned char*)fsmooth->data)[j]]] );
 
1765
                                }
 
1766
                        }
 
1767
                        txavg = txavg / j;
 
1768
                        for(j = 0; j < ECHO_TX_COUNT - 1; j++) {
 
1769
                                i->txavg[j] = i->txavg[j+1];
 
1770
                        }
 
1771
                        i->txavg[ECHO_TX_COUNT - 1] = txavg;
 
1772
                } else {
 
1773
                        if ((i->txgain == 1.0) || (!tcap_is_digital(c->transfercapability))) {
 
1774
                                for (j = 0; j < fsmooth->datalen; j++) {
 
1775
                                        buf[j] = reversebits[((unsigned char *)fsmooth->data)[j]];
 
1776
                                }
 
1777
                        } else {
 
1778
                                for (j = 0; j < fsmooth->datalen; j++) {
 
1779
                                        buf[j] = i->g.txgains[reversebits[((unsigned char *)fsmooth->data)[j]]];
 
1780
                                }
 
1781
                        }
 
1782
                }
 
1783
   
 
1784
                error = 1; 
 
1785
                if (i->B3q > 0) {
 
1786
                        error = _capi_put_cmsg(&CMSG);
 
1787
                } else {
 
1788
                        cc_verbose(3, 1, VERBOSE_PREFIX_4 "%s: too much voice to send for NCCI=%#x\n",
 
1789
                                i->vname, i->NCCI);
 
1790
                }
 
1791
 
 
1792
                if (!error) {
 
1793
                        cc_mutex_lock(&i->lock);
 
1794
                        i->B3q -= fsmooth->datalen;
 
1795
                        if (i->B3q < 0)
 
1796
                                i->B3q = 0;
 
1797
                        cc_mutex_unlock(&i->lock);
 
1798
                }
 
1799
        }
 
1800
        return ret;
 
1801
}
 
1802
 
 
1803
/*
 
1804
 * new channel (masq)
 
1805
 */
 
1806
static int pbx_capi_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
 
1807
{
 
1808
        struct capi_pvt *i = CC_CHANNEL_PVT(newchan);
 
1809
 
 
1810
        cc_verbose(3, 1, VERBOSE_PREFIX_2 "%s: %s fixup now %s\n",
 
1811
                i->vname, oldchan->name, newchan->name);
 
1812
 
 
1813
        cc_mutex_lock(&i->lock);
 
1814
        i->owner = newchan;
 
1815
        cc_mutex_unlock(&i->lock);
 
1816
        return 0;
 
1817
}
 
1818
 
 
1819
/*
 
1820
 * activate (another B protocol)
 
1821
 */
 
1822
static void cc_select_b(struct capi_pvt *i, _cstruct b3conf)
 
1823
{
 
1824
        _cmsg CMSG;
 
1825
 
 
1826
        SELECT_B_PROTOCOL_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(), 0);
 
1827
        SELECT_B_PROTOCOL_REQ_PLCI(&CMSG) = i->PLCI;
 
1828
        SELECT_B_PROTOCOL_REQ_B1PROTOCOL(&CMSG) = b_protocol_table[i->bproto].b1protocol;
 
1829
        SELECT_B_PROTOCOL_REQ_B2PROTOCOL(&CMSG) = b_protocol_table[i->bproto].b2protocol;
 
1830
        SELECT_B_PROTOCOL_REQ_B3PROTOCOL(&CMSG) = b_protocol_table[i->bproto].b3protocol;
 
1831
        SELECT_B_PROTOCOL_REQ_B1CONFIGURATION(&CMSG) = b_protocol_table[i->bproto].b1configuration;
 
1832
        SELECT_B_PROTOCOL_REQ_B2CONFIGURATION(&CMSG) = b_protocol_table[i->bproto].b2configuration;
 
1833
        if (!b3conf)
 
1834
                b3conf = b_protocol_table[i->bproto].b3configuration;
 
1835
        SELECT_B_PROTOCOL_REQ_B3CONFIGURATION(&CMSG) = b3conf;
 
1836
#ifndef CC_HAVE_NO_GLOBALCONFIGURATION
 
1837
        SELECT_B_PROTOCOL_REQ_GLOBALCONFIGURATION(&CMSG) = capi_set_global_configuration(i);
 
1838
#endif
 
1839
 
 
1840
        _capi_put_cmsg(&CMSG);
 
1841
}
 
1842
 
 
1843
/*
 
1844
 * do line initerconnect
 
1845
 */
 
1846
static int line_interconnect(struct capi_pvt *i0, struct capi_pvt *i1, int start)
 
1847
{
 
1848
        _cmsg CMSG;
 
1849
        char buf[20];
 
1850
 
 
1851
        if ((i0->isdnstate & CAPI_ISDN_STATE_DISCONNECT) ||
 
1852
            (i1->isdnstate & CAPI_ISDN_STATE_DISCONNECT))
 
1853
                return -1;
 
1854
 
 
1855
        if ((!(i0->isdnstate & CAPI_ISDN_STATE_B3_UP)) || 
 
1856
            (!(i1->isdnstate & CAPI_ISDN_STATE_B3_UP))) {
 
1857
                cc_verbose(3, 1, VERBOSE_PREFIX_2
 
1858
                        "%s:%s line interconnect aborted, at least "
 
1859
                        "one channel is not connected.\n",
 
1860
                        i0->vname, i1->vname);
 
1861
                return -1;
 
1862
        }
 
1863
 
 
1864
        FACILITY_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(), 0);
 
1865
        FACILITY_REQ_PLCI(&CMSG) = i0->PLCI;
 
1866
        FACILITY_REQ_FACILITYSELECTOR(&CMSG) = FACILITYSELECTOR_LINE_INTERCONNECT;
 
1867
 
 
1868
        memset(buf, 0, sizeof(buf));
 
1869
 
 
1870
        if (start) {
 
1871
                /* connect */
 
1872
                buf[0] = 17; /* msg size */
 
1873
                write_capi_word(&buf[1], 0x0001);
 
1874
                buf[3] = 14; /* struct size LI Request Parameter */
 
1875
                write_capi_dword(&buf[4], 0x00000000); /* Data Path */
 
1876
                buf[8] = 9; /* struct size */
 
1877
                buf[9] = 8; /* struct size LI Request Connect Participant */
 
1878
                write_capi_dword(&buf[10], i1->PLCI);
 
1879
                write_capi_dword(&buf[14], 0x00000003); /* Data Path Participant */
 
1880
        } else {
 
1881
                /* disconnect */
 
1882
                buf[0] = 7; /* msg size */
 
1883
                write_capi_word(&buf[1], 0x0002);
 
1884
                buf[3] = 4; /* struct size */
 
1885
                write_capi_dword(&buf[4], i1->PLCI);
 
1886
        }
 
1887
 
 
1888
        FACILITY_REQ_FACILITYREQUESTPARAMETER(&CMSG) = (_cstruct)buf;
 
1889
        
 
1890
        _capi_put_cmsg(&CMSG);
 
1891
 
 
1892
        if (start) {
 
1893
                i0->isdnstate |= CAPI_ISDN_STATE_LI;
 
1894
                i1->isdnstate |= CAPI_ISDN_STATE_LI;
 
1895
        } else {
 
1896
                i0->isdnstate &= ~CAPI_ISDN_STATE_LI;
 
1897
                i1->isdnstate &= ~CAPI_ISDN_STATE_LI;
 
1898
        }
 
1899
        return 0;
 
1900
}
 
1901
 
 
1902
#if 0
 
1903
/*
 
1904
 * disconnect b3 and bring it up with another protocol
 
1905
 */
 
1906
static void cc_switch_b_protocol(struct capi_pvt *i)
 
1907
{
 
1908
        int waitcount = 200;
 
1909
 
 
1910
        cc_disconnect_b3(i, 1);
 
1911
 
 
1912
        i->isdnstate |= CAPI_ISDN_STATE_B3_CHANGE;
 
1913
        cc_select_b(i, NULL);
 
1914
 
 
1915
        if (i->outgoing) {
 
1916
                /* on outgoing call we must do the connect-b3 request */
 
1917
                cc_start_b3(i);
 
1918
        }
 
1919
 
 
1920
        /* wait for the B3 layer to come up */
 
1921
        while ((waitcount > 0) &&
 
1922
               (!(i->isdnstate & CAPI_ISDN_STATE_B3_UP))) {
 
1923
                usleep(10000);
 
1924
                waitcount--;
 
1925
        }
 
1926
        if (!(i->isdnstate & CAPI_ISDN_STATE_B3_UP)) {
 
1927
                cc_log(LOG_ERROR, "capi switch b3: no b3 up\n");
 
1928
        }
 
1929
}
 
1930
 
 
1931
/*
 
1932
 * set the b3 protocol to transparent
 
1933
 */
 
1934
static int cc_set_transparent(struct capi_pvt *i)
 
1935
{
 
1936
        if (i->bproto != CC_BPROTO_RTP) {
 
1937
                /* nothing to do */
 
1938
                return 0;
 
1939
        }
 
1940
 
 
1941
        i->bproto = CC_BPROTO_TRANSPARENT;
 
1942
        cc_switch_b_protocol(i);
 
1943
 
 
1944
        return 1;
 
1945
}
 
1946
 
 
1947
/*
 
1948
 * set the b3 protocol to RTP (if wanted)
 
1949
 */
 
1950
static void cc_unset_transparent(struct capi_pvt *i, int rtpwanted)
 
1951
{
 
1952
        if ((!rtpwanted) ||
 
1953
            (i->isdnstate & CAPI_ISDN_STATE_DISCONNECT))
 
1954
                return;
 
1955
 
 
1956
        i->bproto = CC_BPROTO_RTP;
 
1957
        cc_switch_b_protocol(i);
 
1958
 
 
1959
        return;
 
1960
}
 
1961
#endif
 
1962
 
 
1963
/*
 
1964
 * native bridging / line interconnect
 
1965
 */
 
1966
static CC_BRIDGE_RETURN pbx_capi_bridge(struct ast_channel *c0,
 
1967
                                    struct ast_channel *c1,
 
1968
                                    int flags, struct ast_frame **fo,
 
1969
                                    struct ast_channel **rc,
 
1970
                                    int timeoutms)
 
1971
{
 
1972
        struct capi_pvt *i0 = CC_CHANNEL_PVT(c0);
 
1973
        struct capi_pvt *i1 = CC_CHANNEL_PVT(c1);
 
1974
        CC_BRIDGE_RETURN ret = AST_BRIDGE_COMPLETE;
 
1975
 
 
1976
        cc_verbose(3, 1, VERBOSE_PREFIX_2 "%s:%s Requested native bridge for %s and %s\n",
 
1977
                i0->vname, i1->vname, c0->name, c1->name);
 
1978
 
 
1979
        if ((!i0->bridge) || (!i1->bridge))
 
1980
                return AST_BRIDGE_FAILED_NOWARN;
 
1981
 
 
1982
        if ((!capi_controllers[i0->controller]->lineinterconnect) ||
 
1983
            (!capi_controllers[i1->controller]->lineinterconnect)) {
 
1984
                return AST_BRIDGE_FAILED_NOWARN;
 
1985
        }
 
1986
 
 
1987
        if ((i0->isdnstate & CAPI_ISDN_STATE_ECT) ||
 
1988
            (i0->isdnstate & CAPI_ISDN_STATE_ECT)) {
 
1989
                return AST_BRIDGE_FAILED;
 
1990
        }
 
1991
        
 
1992
        capi_wait_for_b3_up(i0);
 
1993
        capi_wait_for_b3_up(i1);
 
1994
 
 
1995
        if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0))
 
1996
                capi_detect_dtmf(i0->owner, 0);
 
1997
 
 
1998
        if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1))
 
1999
                capi_detect_dtmf(i1->owner, 0);
 
2000
 
 
2001
        capi_echo_canceller(i0->owner, EC_FUNCTION_DISABLE);
 
2002
        capi_echo_canceller(i1->owner, EC_FUNCTION_DISABLE);
 
2003
 
 
2004
        if (line_interconnect(i0, i1, 1)) {
 
2005
                ret = AST_BRIDGE_FAILED;
 
2006
                goto return_from_bridge;
 
2007
        }
 
2008
 
 
2009
        for (;;) {
 
2010
                struct ast_channel *c0_priority[2] = {c0, c1};
 
2011
                struct ast_channel *c1_priority[2] = {c1, c0};
 
2012
                int priority = 0;
 
2013
                struct ast_frame *f;
 
2014
                struct ast_channel *who;
 
2015
 
 
2016
                who = ast_waitfor_n(priority ? c0_priority : c1_priority, 2, &timeoutms);
 
2017
                if (!who) {
 
2018
                        if (!timeoutms) {
 
2019
                                ret = AST_BRIDGE_RETRY;
 
2020
                                break;
 
2021
                        }
 
2022
                        continue;
 
2023
                }
 
2024
                f = ast_read(who);
 
2025
                if (!f || (f->frametype == AST_FRAME_CONTROL)
 
2026
                       || (f->frametype == AST_FRAME_DTMF)) {
 
2027
                        *fo = f;
 
2028
                        *rc = who;
 
2029
                        ret = AST_BRIDGE_COMPLETE;
 
2030
                        break;
 
2031
                }
 
2032
                if (who == c0) {
 
2033
                        ast_write(c1, f);
 
2034
                } else {
 
2035
                        ast_write(c0, f);
 
2036
                }
 
2037
                ast_frfree(f);
 
2038
 
 
2039
                /* Swap who gets priority */
 
2040
                priority = !priority;
 
2041
        }
 
2042
 
 
2043
        line_interconnect(i0, i1, 0);
 
2044
 
 
2045
return_from_bridge:
 
2046
 
 
2047
        if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0))
 
2048
                capi_detect_dtmf(i0->owner, 1);
 
2049
 
 
2050
        if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1))
 
2051
                capi_detect_dtmf(i1->owner, 1);
 
2052
 
 
2053
        capi_echo_canceller(i0->owner, EC_FUNCTION_ENABLE);
 
2054
        capi_echo_canceller(i1->owner, EC_FUNCTION_ENABLE);
 
2055
 
 
2056
        return ret;
 
2057
}
 
2058
 
 
2059
/*
 
2060
 * a new channel is needed
 
2061
 */
 
2062
static struct ast_channel *capi_new(struct capi_pvt *i, int state)
 
2063
{
 
2064
        struct ast_channel *tmp;
 
2065
        int fmt;
 
2066
        int fds[2];
 
2067
        int flags;
 
2068
 
 
2069
        tmp = ast_channel_alloc(0);
 
2070
        
 
2071
        if (tmp == NULL) {
 
2072
                cc_log(LOG_ERROR,"Unable to allocate channel!\n");
 
2073
                return(NULL);
 
2074
        }
 
2075
 
 
2076
#ifdef CC_AST_HAS_STRINGFIELD_IN_CHANNEL
 
2077
        ast_string_field_build(tmp, name, "CAPI/%s/%s-%x",
 
2078
                i->name, i->dnid, capi_counter++);
 
2079
#else
 
2080
        snprintf(tmp->name, sizeof(tmp->name) - 1, "CAPI/%s/%s-%x",
 
2081
                i->name, i->dnid, capi_counter++);
 
2082
#endif
 
2083
        tmp->type = channeltype;
 
2084
 
 
2085
        if (pipe(fds) != 0) {
 
2086
                cc_log(LOG_ERROR, "%s: unable to create pipe.\n",
 
2087
                        i->vname);
 
2088
                ast_channel_free(tmp);
 
2089
                return NULL;
 
2090
        }
 
2091
        i->readerfd = fds[0];
 
2092
        i->writerfd = fds[1];
 
2093
        flags = fcntl(i->readerfd, F_GETFL);
 
2094
        fcntl(i->readerfd, F_SETFL, flags | O_NONBLOCK);
 
2095
        flags = fcntl(i->writerfd, F_GETFL);
 
2096
        fcntl(i->writerfd, F_SETFL, flags | O_NONBLOCK);
 
2097
 
 
2098
        tmp->fds[0] = i->readerfd;
 
2099
 
 
2100
        if (i->smoother != NULL) {
 
2101
                ast_smoother_reset(i->smoother, CAPI_MAX_B3_BLOCK_SIZE);
 
2102
        }
 
2103
 
1025
2104
        i->state = CAPI_STATE_DISCONNECTED;
1026
 
        i->CLIR = 0;
1027
 
        i->calledPartyIsISDN = 0; // let's be pessimistic
1028
 
        i->earlyB3 = -1;
1029
 
        i->doB3 = AST_CAPI_B3_DONT;
 
2105
        i->calledPartyIsISDN = 1;
 
2106
        i->doB3 = CAPI_B3_DONT;
 
2107
        i->doES = i->ES;
1030
2108
        i->outgoing = 0;
1031
2109
        i->onholdPLCI = 0;
1032
 
#ifdef CAPI_SYNC
1033
 
        i->B3in = 0;
1034
 
        ast_mutex_init(&i->lockB3in);
1035
 
#endif          
1036
 
#ifdef CAPI_ES
1037
 
        memset(i->txavg,0,ECHO_TX_COUNT);
1038
 
#endif
 
2110
        i->doholdtype = i->holdtype;
 
2111
        i->B3q = 0;
 
2112
        memset(i->txavg, 0, ECHO_TX_COUNT);
1039
2113
 
1040
 
#ifndef FORCE_SOFTWARE_DTMF
1041
 
            if (i->doDTMF == 1) {
1042
 
#endif
 
2114
        if (i->doDTMF > 0) {
1043
2115
                i->vad = ast_dsp_new();
1044
 
                ast_dsp_set_features(i->vad,DSP_FEATURE_DTMF_DETECT);
1045
 
#ifndef FORCE_SOFTWARE_DTMF
1046
 
            }
1047
 
#endif
1048
 
 
1049
 
        if (tmp->pvt == NULL) {
1050
 
            free(tmp);
1051
 
            return NULL;
 
2116
                ast_dsp_set_features(i->vad, DSP_FEATURE_DTMF_DETECT);
 
2117
                if (i->doDTMF > 1) {
 
2118
                        ast_dsp_digitmode(i->vad, DSP_DIGITMODE_DTMF | DSP_DIGITMODE_RELAXDTMF);
 
2119
                }
1052
2120
        }
1053
 
        tmp->pvt->pvt = i;
 
2121
 
 
2122
        CC_CHANNEL_PVT(tmp) = i;
1054
2123
 
1055
2124
        tmp->callgroup = i->callgroup;
1056
 
        tmp->pvt->call = capi_call;
1057
 
        tmp->pvt->fixup = capi_fixup;
1058
 
        tmp->pvt->indicate = capi_indicate;
1059
 
        tmp->pvt->bridge = capi_bridge;
1060
 
        tmp->pvt->answer = capi_answer;
1061
 
        tmp->pvt->hangup = capi_hangup;
1062
 
        tmp->pvt->read = capi_read;
1063
 
        tmp->pvt->write = capi_write;
1064
 
        tmp->pvt->send_digit = capi_send_digit;
 
2125
        tmp->pickupgroup = i->pickupgroup;
1065
2126
        tmp->nativeformats = capi_capability;
 
2127
        i->bproto = CC_BPROTO_TRANSPARENT;
 
2128
        if ((i->rtpcodec = (capi_controllers[i->controller]->rtpcodec & i->capability))) {
 
2129
                if (capi_alloc_rtp(i)) {
 
2130
                        /* error on rtp alloc */
 
2131
                        i->rtpcodec = 0;
 
2132
                } else {
 
2133
                        /* start with rtp */
 
2134
                        tmp->nativeformats = i->rtpcodec;
 
2135
                        i->bproto = CC_BPROTO_RTP;
 
2136
                }
 
2137
        }
1066
2138
        fmt = ast_best_codec(tmp->nativeformats);
1067
 
//      fmt = capi_capability;
 
2139
        i->codec = fmt;
1068
2140
        tmp->readformat = fmt;
1069
2141
        tmp->writeformat = fmt;
1070
 
        tmp->pvt->rawreadformat = fmt;
1071
 
        tmp->pvt->rawwriteformat = fmt;
1072
 
        strncpy(tmp->context,i->context,sizeof(tmp->context)-1);
1073
 
        tmp->callerid = strdup(i->cid);
1074
 
        tmp->dnid = strdup(i->dnid);
1075
 
        strncpy(tmp->exten,i->dnid,sizeof(tmp->exten)-1);
1076
 
        strncpy(tmp->accountcode,i->accountcode,sizeof(tmp->accountcode)-1);
 
2142
 
 
2143
        tmp->tech = &capi_tech;
 
2144
        tmp->rawreadformat = fmt;
 
2145
        tmp->rawwriteformat = fmt;
 
2146
 
 
2147
        cc_verbose(3, 1, VERBOSE_PREFIX_2 "%s: setting format %s - %s%s\n",
 
2148
                i->vname, ast_getformatname(fmt),
 
2149
                ast_getformatname_multiple(alloca(80), 80,
 
2150
                tmp->nativeformats),
 
2151
                (i->rtp) ? " (RTP)" : "");
 
2152
        cc_copy_string(tmp->context, i->context, sizeof(tmp->context));
 
2153
 
 
2154
        if (!ast_strlen_zero(i->cid)) {
 
2155
                if (tmp->cid.cid_num) {
 
2156
                        free(tmp->cid.cid_num);
 
2157
                }
 
2158
                tmp->cid.cid_num = strdup(i->cid);
 
2159
        }
 
2160
        if (!ast_strlen_zero(i->dnid)) {
 
2161
                if (tmp->cid.cid_dnid) {
 
2162
                        free(tmp->cid.cid_dnid);
 
2163
                }
 
2164
                tmp->cid.cid_dnid = strdup(i->dnid);
 
2165
        }
 
2166
        tmp->cid.cid_ton = i->cid_ton;
 
2167
        if (i->amaflags)
 
2168
                tmp->amaflags = i->amaflags;
 
2169
        
 
2170
        cc_copy_string(tmp->exten, i->dnid, sizeof(tmp->exten));
 
2171
#ifdef CC_AST_HAS_STRINGFIELD_IN_CHANNEL
 
2172
        ast_string_field_set(tmp, accountcode, i->accountcode);
 
2173
        ast_string_field_set(tmp, language, i->language);
 
2174
#else
 
2175
        cc_copy_string(tmp->accountcode, i->accountcode, sizeof(tmp->accountcode));
 
2176
        cc_copy_string(tmp->language, i->language, sizeof(tmp->language));
 
2177
#endif
1077
2178
        i->owner = tmp;
1078
 
        ast_mutex_lock(&usecnt_lock);
 
2179
        cc_mutex_lock(&usecnt_lock);
1079
2180
        usecnt++;
1080
 
        ast_mutex_unlock(&usecnt_lock);
 
2181
        cc_mutex_unlock(&usecnt_lock);
1081
2182
        ast_update_use_count();
1082
 
        if (state != AST_STATE_DOWN) {
1083
 
            // we are alerting (phones ringing)
1084
 
            if (state == AST_STATE_RING)
1085
 
                capi_alert(tmp);
1086
 
            if (ast_pbx_start(tmp)) {
1087
 
                ast_log(LOG_ERROR,"Unable to start pbx on channel!\n");
1088
 
                ast_hangup(tmp);
1089
 
                tmp = NULL;
1090
 
            } else {
1091
 
                if (option_verbose > 2) {
1092
 
                    ast_verbose(VERBOSE_PREFIX_3 "started pbx on channel (callgroup=%d)!\n",tmp->callgroup);
1093
 
                }
1094
 
            }
1095
 
        }
1096
 
    } else {
1097
 
        ast_log(LOG_ERROR,"Unable to allocate channel!\n");
1098
 
    }
1099
 
    return tmp;
 
2183
        
 
2184
        ast_setstate(tmp, state);
 
2185
 
 
2186
        return tmp;
1100
2187
}
1101
2188
 
1102
 
 
1103
 
struct ast_channel *capi_request(char *type, int format, void *data)
 
2189
/*
 
2190
 * PBX wants us to dial ...
 
2191
 */
 
2192
static struct ast_channel *
 
2193
pbx_capi_request(const char *type, int format, void *data, int *cause)
1104
2194
{
1105
 
        struct ast_capi_pvt *i;
 
2195
        struct capi_pvt *i;
1106
2196
        struct ast_channel *tmp = NULL;
1107
 
        char *dest,*omsn,*msn;
1108
 
        char buffer[AST_MAX_EXTENSION];
1109
 
        int c=0;
1110
 
        char *stringp,tmpstr[AST_MAX_EXTENSION];
1111
 
 
1112
 
        if (option_verbose > 1) {
1113
 
            if (capidebug)
1114
 
                ast_verbose(VERBOSE_PREFIX_3 "data = %s\n",(char *)data);
1115
 
        }
1116
 
        strncpy(buffer,(char *)data,sizeof(buffer)-1);
1117
 
 
1118
 
        omsn = strtok(buffer, ":");
1119
 
        dest = strtok(NULL, ":");
1120
 
 
1121
 
        if (option_verbose > 1) {
1122
 
            if (capidebug)
1123
 
                ast_verbose(VERBOSE_PREFIX_3 "capi request omsn = %s\n",omsn);
1124
 
        }
1125
 
        
1126
 
        if (((char *)omsn)[0] == '@') {
1127
 
            omsn++;
1128
 
        }
1129
 
 
1130
 
        ast_mutex_lock(&iflock);
1131
 
        i = iflist;
1132
 
        while (i) {
1133
 
            strncpy(tmpstr,i->msn,sizeof(tmpstr)-1);
1134
 
            stringp=tmpstr;
1135
 
            msn = strsep(&stringp,",");
1136
 
            while (msn != NULL) {
1137
 
                if (!strcmp(omsn,msn) ||
1138
 
                    (i->isdnmode && (strlen(msn)<=strlen(omsn)) && !strncmp(omsn, msn,strlen(msn)))) {
1139
 
                    // unused channel
1140
 
                    if (!i->owner) {
1141
 
                        if (option_verbose > 1) {
1142
 
                            if (capidebug)
1143
 
                                ast_verbose(VERBOSE_PREFIX_2 "found capi with omsn = %s\n",omsn);
1144
 
                        }
1145
 
 
1146
 
                        ast_mutex_lock(&contrlock);
1147
 
                        for (c=1;c<=AST_CAPI_MAX_CONTROLLERS;c++) {
1148
 
                            if (i->controllers & (1 << c)) { 
1149
 
                                if (capi_controllers[c]->nfreebchannels > 0) {
1150
 
                                    i->controller = c;
1151
 
                                    strncpy(i->dnid,omsn,sizeof(i->dnid)-1);
1152
 
                                    tmp = capi_new(i, AST_STATE_DOWN);
1153
 
                                    i->PLCI = -1;
1154
 
                                    i->datahandle = 0;
1155
 
                                    i->outgoing = 1;    // this is an outgoing line
1156
 
                                    i->earlyB3 = -1;
1157
 
                                    // capi_detect_dtmf(tmp,1);
1158
 
                                    ast_mutex_unlock(&contrlock);
1159
 
                                    ast_mutex_unlock(&iflock);
1160
 
                                    return tmp;
1161
 
                                }
1162
 
                            }
1163
 
                        }
1164
 
                        ast_mutex_unlock(&contrlock);
1165
 
                        ast_log(LOG_ERROR,"no free b channel on controllers (map=%#x)\n",(int) i->controllers);
1166
 
                    }
1167
 
                }
1168
 
                msn = strsep(&stringp,",");
1169
 
            }
1170
 
            i = i->next;
1171
 
        }
1172
 
        ast_mutex_unlock(&iflock);
1173
 
        ast_log(LOG_NOTICE,"didn't find capi device with outgoing msn = %s. you should check your config!\n",omsn);
1174
 
        return NULL;
1175
 
}
1176
 
 
1177
 
 
1178
 
struct capi_pipe *find_pipe(int PLCI,int MN) {
1179
 
    struct capi_pipe *p;
1180
 
    // find a pipe by PLCI or by MessageNumber (in case this is a CONNECT_CONF)
1181
 
    ast_mutex_lock(&pipelock);
1182
 
    p = pipelist;
1183
 
    if ((p == NULL) && (capi_last_plci != PLCI)){
1184
 
        if (capidebug) {
1185
 
        ast_log(LOG_NOTICE,"PLCI doesnt match last pipe (PLCI = %#x)\n",PLCI);
1186
 
        }
1187
 
        ast_mutex_unlock(&pipelock);
1188
 
        return NULL;
1189
 
    }
1190
 
    while(p != NULL) {
1191
 
        if ((p->PLCI == PLCI) || ( (p->PLCI == -1) && (p->i->MessageNumber == MN) ) ){
1192
 
            ast_mutex_unlock(&pipelock);
1193
 
            return p;
1194
 
        }
1195
 
        p = p->next;
1196
 
    }
1197
 
    if (capidebug) {
1198
 
        ast_log(LOG_ERROR,"unable to find a pipe for PLCI = %#x MN = %#x\n",PLCI,MN);
1199
 
    }
1200
 
    ast_mutex_unlock(&pipelock);
1201
 
    return NULL;
1202
 
}
1203
 
 
1204
 
int pipe_frame(struct capi_pipe *p,struct ast_frame *f) {
1205
 
        fd_set wfds;
1206
 
        int written=0;
1207
 
        struct timeval tv;
1208
 
        FD_ZERO(&wfds);
1209
 
        FD_SET(p->fd,&wfds);
1210
 
        tv.tv_sec = 0;
1211
 
        tv.tv_usec = 10;
1212
 
        if ((f->frametype == AST_FRAME_VOICE) && (p->i->doDTMF == 1) && (p->i->vad != NULL)) {
1213
 
#ifdef UNSTABLE_CVS
1214
 
            f = ast_dsp_process(p->c,p->i->vad,f);
1215
 
#else
1216
 
            f = ast_dsp_process(p->c,p->i->vad,f, 0);
1217
 
#endif
1218
 
            if (f->frametype == AST_FRAME_NULL) {
1219
 
                return 0;
1220
 
            }
1221
 
        }
1222
 
        // we dont want the monitor thread to block
1223
 
        if (select(p->fd + 1,NULL,&wfds,NULL,&tv) == 1) {
1224
 
            written = write(p->fd,f,sizeof(struct ast_frame));
1225
 
            if (written < (signed int) sizeof(struct ast_frame)) {
1226
 
                ast_log(LOG_ERROR,"wrote %d bytes instead of %d\n",written,sizeof(struct ast_frame));
1227
 
                return -1;
1228
 
            }
1229
 
            if (f->frametype == AST_FRAME_VOICE) {
1230
 
                written = write(p->fd,f->data,f->datalen);
1231
 
                if (written < f->datalen) {
1232
 
                    ast_log(LOG_ERROR,"wrote %d bytes instead of %d\n",written,f->datalen);
1233
 
                    return -1;
1234
 
                }
1235
 
            }
1236
 
        } else {
1237
 
            return 0;
1238
 
        }
1239
 
        return -1;
1240
 
}
1241
 
 
 
2197
        char *dest, *interface, *param, *ocid;
 
2198
        char buffer[CAPI_MAX_STRING];
 
2199
        ast_group_t capigroup = 0;
 
2200
        unsigned int controller = 0;
 
2201
        int notfound = 1;
 
2202
 
 
2203
        cc_verbose(1, 1, VERBOSE_PREFIX_4 "data = %s format=%d\n", (char *)data, format);
 
2204
 
 
2205
        cc_copy_string(buffer, (char *)data, sizeof(buffer));
 
2206
        parse_dialstring(buffer, &interface, &dest, &param, &ocid);
 
2207
 
 
2208
        if ((!interface) || (!dest)) {
 
2209
                cc_log(LOG_ERROR, "Syntax error in dialstring. Read the docs!\n");
 
2210
                *cause = AST_CAUSE_INVALID_NUMBER_FORMAT;
 
2211
                return NULL;
 
2212
        }
 
2213
 
 
2214
        if (interface[0] == 'g') {
 
2215
                capigroup = ast_get_group(interface + 1);
 
2216
                cc_verbose(1, 1, VERBOSE_PREFIX_4 "capi request group = %d\n",
 
2217
                                (unsigned int)capigroup);
 
2218
        } else if (!strncmp(interface, "contr", 5)) {
 
2219
                controller = atoi(interface + 5);
 
2220
                cc_verbose(1, 1, VERBOSE_PREFIX_4 "capi request controller = %d\n",
 
2221
                                controller);
 
2222
        } else {
 
2223
                cc_verbose(1, 1, VERBOSE_PREFIX_4 "capi request for interface '%s'\n",
 
2224
                                interface);
 
2225
        }
 
2226
 
 
2227
        cc_mutex_lock(&iflock);
 
2228
        
 
2229
        for (i = iflist; (i && notfound); i = i->next) {
 
2230
                if ((i->owner) || (i->channeltype != CAPI_CHANNELTYPE_B)) {
 
2231
                        /* if already in use or no real channel */
 
2232
                        continue;
 
2233
                }
 
2234
                /* unused channel */
 
2235
                if (controller) {
 
2236
                        /* DIAL(CAPI/contrX/...) */
 
2237
                        if (i->controller != controller) {
 
2238
                                /* keep on running! */
 
2239
                                continue;
 
2240
                        }
 
2241
                } else {
 
2242
                        /* DIAL(CAPI/gX/...) */
 
2243
                        if ((interface[0] == 'g') && (!(i->group & capigroup))) {
 
2244
                                /* keep on running! */
 
2245
                                continue;
 
2246
                        }
 
2247
                        /* DIAL(CAPI/<interface-name>/...) */
 
2248
                        if ((interface[0] != 'g') && (strcmp(interface, i->name))) {
 
2249
                                /* keep on running! */
 
2250
                                continue;
 
2251
                        }
 
2252
                }
 
2253
                /* when we come here, we found a free controller match */
 
2254
                cc_copy_string(i->dnid, dest, sizeof(i->dnid));
 
2255
                tmp = capi_new(i, AST_STATE_RESERVED);
 
2256
                if (!tmp) {
 
2257
                        cc_log(LOG_ERROR, "cannot create new capi channel\n");
 
2258
                        interface_cleanup(i);
 
2259
                }
 
2260
                i->PLCI = 0;
 
2261
                i->outgoing = 1;        /* this is an outgoing line */
 
2262
                cc_mutex_unlock(&iflock);
 
2263
                return tmp;
 
2264
        }
 
2265
        cc_mutex_unlock(&iflock);
 
2266
        cc_verbose(2, 0, VERBOSE_PREFIX_3 "didn't find capi device for interface '%s'\n",
 
2267
                interface);
 
2268
        *cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL;
 
2269
        return NULL;
 
2270
}
 
2271
 
 
2272
/*
 
2273
 * fill out fax conf struct
 
2274
 */
 
2275
static void setup_b3_fax_config(B3_PROTO_FAXG3 *b3conf, int fax_format, char *stationid, char *headline)
 
2276
{
 
2277
        int len1;
 
2278
        int len2;
 
2279
 
 
2280
        cc_verbose(3, 1, VERBOSE_PREFIX_3 "Setup fax b3conf fmt=%d, stationid='%s' headline='%s'\n",
 
2281
                fax_format, stationid, headline);
 
2282
        b3conf->resolution = 0;
 
2283
        b3conf->format = (unsigned short)fax_format;
 
2284
        len1 = strlen(stationid);
 
2285
        b3conf->Infos[0] = (unsigned char)len1;
 
2286
        strcpy((char *)&b3conf->Infos[1], stationid);
 
2287
        len2 = strlen(headline);
 
2288
        b3conf->Infos[len1 + 1] = (unsigned char)len2;
 
2289
        strcpy((char *)&b3conf->Infos[len1 + 2], headline);
 
2290
        b3conf->len = (unsigned char)(2 * sizeof(unsigned short) + len1 + len2 + 2);
 
2291
        return;
 
2292
}
 
2293
 
 
2294
/*
 
2295
 * change b protocol to fax
 
2296
 */
 
2297
static void capi_change_bchan_fax(struct ast_channel *c, B3_PROTO_FAXG3 *b3conf) 
 
2298
{
 
2299
        struct capi_pvt *i = CC_CHANNEL_PVT(c);
 
2300
 
 
2301
        i->isdnstate |= CAPI_ISDN_STATE_B3_SELECT;
 
2302
        cc_disconnect_b3(i, 1);
 
2303
        cc_select_b(i, (_cstruct)b3conf);
 
2304
        return;
 
2305
}
 
2306
 
 
2307
/*
 
2308
 * capicommand 'receivefax'
 
2309
 */
 
2310
static int pbx_capi_receive_fax(struct ast_channel *c, char *data)
 
2311
{
 
2312
        struct capi_pvt *i = CC_CHANNEL_PVT(c);
 
2313
        int res = 0;
 
2314
        char *filename, *stationid, *headline;
 
2315
        B3_PROTO_FAXG3 b3conf;
 
2316
        char buffer[CAPI_MAX_STRING];
 
2317
 
 
2318
        if (!data) { /* no data implies no filename or anything is present */
 
2319
                cc_log(LOG_WARNING, "capi receivefax requires a filename\n");
 
2320
                return -1;
 
2321
        }
 
2322
 
 
2323
        filename = strsep(&data, "|");
 
2324
        stationid = strsep(&data, "|");
 
2325
        headline = data;
 
2326
 
 
2327
        if (!stationid)
 
2328
                stationid = emptyid;
 
2329
        if (!headline)
 
2330
                headline = emptyid;
 
2331
 
 
2332
        capi_wait_for_answered(i);
 
2333
 
 
2334
        if ((i->fFax = fopen(filename, "wb")) == NULL) {
 
2335
                cc_log(LOG_WARNING, "can't create fax output file (%s)\n", strerror(errno));
 
2336
                return -1;
 
2337
        }
 
2338
 
 
2339
        i->FaxState |= CAPI_FAX_STATE_ACTIVE;
 
2340
        setup_b3_fax_config(&b3conf, FAX_SFF_FORMAT, stationid, headline);
 
2341
 
 
2342
        i->bproto = CC_BPROTO_FAXG3;
 
2343
 
 
2344
        switch (i->state) {
 
2345
        case CAPI_STATE_ALERTING:
 
2346
        case CAPI_STATE_DID:
 
2347
        case CAPI_STATE_INCALL:
 
2348
                capi_send_answer(c, (_cstruct)&b3conf);
 
2349
                break;
 
2350
        case CAPI_STATE_CONNECTED:
 
2351
                capi_change_bchan_fax(c, &b3conf);
 
2352
                break;
 
2353
        default:
 
2354
                i->FaxState &= ~CAPI_FAX_STATE_ACTIVE;
 
2355
                cc_log(LOG_WARNING, "capi receive fax in wrong state (%d)\n",
 
2356
                        i->state);
 
2357
                return -1;
 
2358
        }
 
2359
        capi_wait_for_fax_finish(i);
 
2360
 
 
2361
        res = (i->FaxState & CAPI_FAX_STATE_ERROR) ? 1 : 0;
 
2362
        i->FaxState &= ~(CAPI_FAX_STATE_ACTIVE | CAPI_FAX_STATE_ERROR);
 
2363
 
 
2364
        /* if the file has zero length */
 
2365
        if (ftell(i->fFax) == 0L) {
 
2366
                res = 1;
 
2367
        }
 
2368
                        
 
2369
        cc_verbose(2, 1, VERBOSE_PREFIX_3 "Closing fax file...\n");
 
2370
        fclose(i->fFax);
 
2371
        i->fFax = NULL;
 
2372
 
 
2373
        if (res != 0) {
 
2374
                cc_verbose(2, 0,
 
2375
                        VERBOSE_PREFIX_1 "capi receivefax: fax receive failed reason=0x%04x reasonB3=0x%04x\n",
 
2376
                                i->reason, i->reasonb3);
 
2377
                unlink(filename);
 
2378
        } else {
 
2379
                cc_verbose(2, 0,
 
2380
                        VERBOSE_PREFIX_1 "capi receivefax: fax receive successful.\n");
 
2381
        }
 
2382
        snprintf(buffer, CAPI_MAX_STRING-1, "%d", res);
 
2383
        pbx_builtin_setvar_helper(c, "FAXSTATUS", buffer);
 
2384
        
 
2385
        return 0;
 
2386
}
 
2387
 
 
2388
/*
 
2389
 * capicommand 'sendfax'
 
2390
 */
 
2391
static int pbx_capi_send_fax(struct ast_channel *c, char *data)
 
2392
{
 
2393
        struct capi_pvt *i = CC_CHANNEL_PVT(c);
 
2394
        int res = 0;
 
2395
        char *filename, *stationid, *headline;
 
2396
        B3_PROTO_FAXG3 b3conf;
 
2397
        char buffer[CAPI_MAX_STRING];
 
2398
 
 
2399
        if (!data) { /* no data implies no filename or anything is present */
 
2400
                cc_log(LOG_WARNING, "capi sendfax requires a filename\n");
 
2401
                return -1;
 
2402
        }
 
2403
 
 
2404
        filename = strsep(&data, "|");
 
2405
        stationid = strsep(&data, "|");
 
2406
        headline = data;
 
2407
 
 
2408
        if (!stationid)
 
2409
                stationid = emptyid;
 
2410
        if (!headline)
 
2411
                headline = emptyid;
 
2412
 
 
2413
        capi_wait_for_answered(i);
 
2414
 
 
2415
        if ((i->fFax = fopen(filename, "rb")) == NULL) {
 
2416
                cc_log(LOG_WARNING, "can't open fax file (%s)\n", strerror(errno));
 
2417
                return -1;
 
2418
        }
 
2419
 
 
2420
        i->FaxState |= (CAPI_FAX_STATE_ACTIVE | CAPI_FAX_STATE_SENDMODE);
 
2421
        setup_b3_fax_config(&b3conf, FAX_SFF_FORMAT, stationid, headline);
 
2422
 
 
2423
        i->bproto = CC_BPROTO_FAXG3;
 
2424
 
 
2425
        switch (i->state) {
 
2426
        case CAPI_STATE_ALERTING:
 
2427
        case CAPI_STATE_DID:
 
2428
        case CAPI_STATE_INCALL:
 
2429
                capi_send_answer(c, (_cstruct)&b3conf);
 
2430
                break;
 
2431
        case CAPI_STATE_CONNECTED:
 
2432
                capi_change_bchan_fax(c, &b3conf);
 
2433
                break;
 
2434
        default:
 
2435
                i->FaxState &= ~CAPI_FAX_STATE_ACTIVE;
 
2436
                cc_log(LOG_WARNING, "capi send fax in wrong state (%d)\n",
 
2437
                        i->state);
 
2438
                return -1;
 
2439
        }
 
2440
        capi_wait_for_fax_finish(i);
 
2441
 
 
2442
        res = (i->FaxState & CAPI_FAX_STATE_ERROR) ? 1 : 0;
 
2443
        i->FaxState &= ~(CAPI_FAX_STATE_ACTIVE | CAPI_FAX_STATE_ERROR);
 
2444
 
 
2445
        /* if the file has zero length */
 
2446
        if (ftell(i->fFax) == 0L) {
 
2447
                res = 1;
 
2448
        }
 
2449
                        
 
2450
        cc_verbose(2, 1, VERBOSE_PREFIX_3 "Closing fax file...\n");
 
2451
        fclose(i->fFax);
 
2452
        i->fFax = NULL;
 
2453
 
 
2454
        if (res != 0) {
 
2455
                cc_verbose(2, 0,
 
2456
                        VERBOSE_PREFIX_1 "capi sendfax: fax send failed reason=0x%04x reasonB3=0x%04x\n",
 
2457
                                i->reason, i->reasonb3);
 
2458
        } else {
 
2459
                cc_verbose(2, 0,
 
2460
                        VERBOSE_PREFIX_1 "capi sendfax: fax sent successful.\n");
 
2461
        }
 
2462
        snprintf(buffer, CAPI_MAX_STRING-1, "%d", res);
 
2463
        pbx_builtin_setvar_helper(c, "FAXSTATUS", buffer);
 
2464
        
 
2465
        return 0;
 
2466
}
 
2467
 
 
2468
/*
 
2469
 * Fax guard tone -- Handle and return NULL
 
2470
 */
 
2471
static void capi_handle_dtmf_fax(struct capi_pvt *i)
 
2472
{
 
2473
        struct ast_channel *c = i->owner;
 
2474
 
 
2475
        if (!c) {
 
2476
                cc_log(LOG_ERROR, "No channel!\n");
 
2477
                return;
 
2478
        }
 
2479
        
 
2480
        if (i->FaxState & CAPI_FAX_STATE_HANDLED) {
 
2481
                cc_log(LOG_DEBUG, "Fax already handled\n");
 
2482
                return;
 
2483
        }
 
2484
        i->FaxState |= CAPI_FAX_STATE_HANDLED;
 
2485
 
 
2486
        if (((i->outgoing == 1) && (!(i->FaxState & CAPI_FAX_DETECT_OUTGOING))) ||
 
2487
            ((i->outgoing == 0) && (!(i->FaxState & CAPI_FAX_DETECT_INCOMING)))) {
 
2488
                cc_verbose(3, 0, VERBOSE_PREFIX_3 "%s: Fax detected, but not configured for redirection\n",
 
2489
                        i->vname);
 
2490
                return;
 
2491
        }
 
2492
        
 
2493
        if (!strcmp(c->exten, "fax")) {
 
2494
                cc_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n");
 
2495
                return;
 
2496
        }
 
2497
 
 
2498
        if (!ast_exists_extension(c, c->context, "fax", 1, i->cid)) {
 
2499
                cc_verbose(3, 0, VERBOSE_PREFIX_3 "Fax tone detected, but no fax extension for %s\n", c->name);
 
2500
                return;
 
2501
        }
 
2502
 
 
2503
        cc_verbose(2, 0, VERBOSE_PREFIX_3 "%s: Redirecting %s to fax extension\n",
 
2504
                i->vname, c->name);
 
2505
                        
 
2506
        /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
 
2507
        pbx_builtin_setvar_helper(c, "FAXEXTEN", c->exten);
 
2508
        
 
2509
        if (ast_async_goto(c, c->context, "fax", 1))
 
2510
                cc_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", c->name, c->context);
 
2511
        return;
 
2512
}
 
2513
 
 
2514
/*
 
2515
 * find the interface (pvt) the PLCI belongs to
 
2516
 */
 
2517
static struct capi_pvt *find_interface_by_plci(unsigned int plci)
 
2518
{
 
2519
        struct capi_pvt *i;
 
2520
 
 
2521
        if (plci == 0)
 
2522
                return NULL;
 
2523
 
 
2524
        cc_mutex_lock(&iflock);
 
2525
        for (i = iflist; i; i = i->next) {
 
2526
                if (i->PLCI == plci)
 
2527
                        break;
 
2528
        }
 
2529
        cc_mutex_unlock(&iflock);
 
2530
 
 
2531
        return i;
 
2532
}
 
2533
 
 
2534
/*
 
2535
 * find the interface (pvt) the messagenumber belongs to
 
2536
 */
 
2537
static struct capi_pvt *find_interface_by_msgnum(unsigned short msgnum)
 
2538
{
 
2539
        struct capi_pvt *i;
 
2540
 
 
2541
        if (msgnum == 0x0000)
 
2542
                return NULL;
 
2543
 
 
2544
        cc_mutex_lock(&iflock);
 
2545
        for (i = iflist; i; i = i->next) {
 
2546
                    if ((i->PLCI == 0) && (i->MessageNumber == msgnum))
 
2547
                        break;
 
2548
        }
 
2549
        cc_mutex_unlock(&iflock);
 
2550
 
 
2551
        return i;
 
2552
}
 
2553
 
 
2554
/*
 
2555
 * see if did matches
 
2556
 */
1242
2557
static int search_did(struct ast_channel *c)
1243
2558
{
1244
 
    // Returns 
1245
 
    // -1 = Failure 
1246
 
    //  0 = Match
1247
 
    //  1 = possible match 
1248
 
    struct ast_capi_pvt *i = c->pvt->pvt;
1249
 
    char *exten;
 
2559
        /*
 
2560
         * Returns 
 
2561
         * -1 = Failure 
 
2562
         *  0 = Match
 
2563
         *  1 = possible match 
 
2564
         */
 
2565
        struct capi_pvt *i = CC_CHANNEL_PVT(c);
 
2566
        char *exten;
1250
2567
    
1251
 
    if (strlen(i->dnid)<strlen(i->incomingmsn))
 
2568
        if (!strlen(i->dnid) && (i->immediate)) {
 
2569
                exten = "s";
 
2570
                cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: %s: %s matches in context %s for immediate\n",
 
2571
                        i->vname, c->name, exten, c->context);
 
2572
        } else {
 
2573
                if (strlen(i->dnid) < strlen(i->incomingmsn))
 
2574
                        return 0;
 
2575
                exten = i->dnid;
 
2576
        }
 
2577
 
 
2578
        if (ast_exists_extension(NULL, c->context, exten, 1, i->cid)) {
 
2579
                c->priority = 1;
 
2580
                cc_copy_string(c->exten, exten, sizeof(c->exten));
 
2581
                cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: %s: %s matches in context %s\n",
 
2582
                        i->vname, c->name, exten, c->context);
 
2583
                return 0;
 
2584
        }
 
2585
 
 
2586
        if (ast_canmatch_extension(NULL, c->context, exten, 1, i->cid)) {
 
2587
                cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: %s: %s would possibly match in context %s\n",
 
2588
                        i->vname, c->name, exten, c->context);
 
2589
                return 1;
 
2590
        }
 
2591
 
1252
2592
        return -1;
1253
 
        
1254
 
//    exten = i->dnid + strlen(i->incomingmsn);
1255
 
    exten = i->dnid;
1256
 
 
1257
 
    if (ast_exists_extension(NULL, c->context, exten, 1, NULL)) {
1258
 
            c->priority = 1;
1259
 
            strncpy(c->exten, exten, sizeof(c->exten) - 1);
1260
 
        return 0;
1261
 
    }
1262
 
 
1263
 
    if (ast_canmatch_extension(NULL, c->context, exten, 1, NULL)) {
1264
 
        return 1;
1265
 
    }
1266
 
 
1267
 
 
1268
 
    return -1;
1269
 
}
1270
 
 
1271
 
int pipe_msg(int PLCI,_cmsg *CMSG) {
1272
 
        struct capi_pipe *p;
1273
 
        _cmsg CMSG2;
1274
 
        MESSAGE_EXCHANGE_ERROR  error;
1275
 
        struct ast_frame fr;
1276
 
        char b3buf[1024];
1277
 
        int j;
1278
 
        int b3len=0;
 
2593
}
 
2594
 
 
2595
/*
 
2596
 * Progress Indicator
 
2597
 */
 
2598
static void handle_progress_indicator(_cmsg *CMSG, unsigned int PLCI, struct capi_pvt *i)
 
2599
{
 
2600
        if (INFO_IND_INFOELEMENT(CMSG)[0] < 2) {
 
2601
                cc_verbose(3, 1, VERBOSE_PREFIX_4 "%s: Progress description missing\n",
 
2602
                        i->vname);
 
2603
                return;
 
2604
        }
 
2605
 
 
2606
        switch(INFO_IND_INFOELEMENT(CMSG)[2] & 0x7f) {
 
2607
        case 0x01:
 
2608
                cc_verbose(4, 1, VERBOSE_PREFIX_4 "%s: Not end-to-end ISDN\n",
 
2609
                        i->vname);
 
2610
                break;
 
2611
        case 0x02:
 
2612
                cc_verbose(4, 1, VERBOSE_PREFIX_4 "%s: Destination is non ISDN\n",
 
2613
                        i->vname);
 
2614
                i->calledPartyIsISDN = 0;
 
2615
                break;
 
2616
        case 0x03:
 
2617
                cc_verbose(4, 1, VERBOSE_PREFIX_4 "%s: Origination is non ISDN\n",
 
2618
                        i->vname);
 
2619
                break;
 
2620
        case 0x04:
 
2621
                cc_verbose(4, 1, VERBOSE_PREFIX_4 "%s: Call returned to ISDN\n",
 
2622
                        i->vname);
 
2623
                break;
 
2624
        case 0x05:
 
2625
                cc_verbose(4, 1, VERBOSE_PREFIX_4 "%s: Interworking occured\n",
 
2626
                        i->vname);
 
2627
                break;
 
2628
        case 0x08:
 
2629
                cc_verbose(4, 1, VERBOSE_PREFIX_4 "%s: In-band information available\n",
 
2630
                        i->vname);
 
2631
                break;
 
2632
        default:
 
2633
                cc_verbose(3, 1, VERBOSE_PREFIX_4 "%s: Unknown progress description %02x\n",
 
2634
                        i->vname, INFO_IND_INFOELEMENT(CMSG)[2]);
 
2635
        }
 
2636
        send_progress(i);
 
2637
        return;
 
2638
}
 
2639
 
 
2640
/*
 
2641
 * if the dnid matches, start the pbx
 
2642
 */
 
2643
static void start_pbx_on_match(struct capi_pvt *i, unsigned int PLCI, _cword MessageNumber)
 
2644
{
 
2645
        struct ast_channel *c;
 
2646
        _cmsg CMSG2;
 
2647
 
 
2648
        c = i->owner;
 
2649
 
 
2650
        if ((i->isdnstate & CAPI_ISDN_STATE_PBX_DONT)) {
 
2651
                /* we already found non-match here */
 
2652
                return;
 
2653
        }
 
2654
        if ((i->isdnstate & CAPI_ISDN_STATE_PBX)) {
 
2655
                cc_verbose(3, 1, VERBOSE_PREFIX_2 "%s: pbx already started on channel %s\n",
 
2656
                        i->vname, c->name);
 
2657
                return;
 
2658
        }
 
2659
 
 
2660
        /* check for internal pickup extension first */
 
2661
        if (!strcmp(i->dnid, ast_pickup_ext())) {
 
2662
                i->isdnstate |= CAPI_ISDN_STATE_PBX;
 
2663
                cc_verbose(3, 1, VERBOSE_PREFIX_2 "%s: Pickup extension '%s' found.\n",
 
2664
                        i->vname, i->dnid);
 
2665
                cc_copy_string(c->exten, i->dnid, sizeof(c->exten));
 
2666
                pbx_capi_alert(c);
 
2667
                capi_channel_task(c, CAPI_CHANNEL_TASK_PICKUP);
 
2668
                return;
 
2669
        }
 
2670
 
 
2671
        switch(search_did(i->owner)) {
 
2672
        case 0: /* match */
 
2673
                i->isdnstate |= CAPI_ISDN_STATE_PBX;
 
2674
                ast_setstate(c, AST_STATE_RING);
 
2675
                if (ast_pbx_start(i->owner)) {
 
2676
                        cc_log(LOG_ERROR, "%s: Unable to start pbx on channel!\n",
 
2677
                                i->vname);
 
2678
                        capi_channel_task(c, CAPI_CHANNEL_TASK_HANGUP); 
 
2679
                } else {
 
2680
                        cc_verbose(2, 1, VERBOSE_PREFIX_2 "Started pbx on channel %s\n",
 
2681
                                c->name);
 
2682
                }
 
2683
                break;
 
2684
        case 1:
 
2685
                /* would possibly match */
 
2686
                if (i->isdnmode == CAPI_ISDNMODE_DID)
 
2687
                        break;
 
2688
                /* fall through for MSN mode, because there won't be a longer msn */
 
2689
        case -1:
 
2690
        default:
 
2691
                /* doesn't match */
 
2692
                i->isdnstate |= CAPI_ISDN_STATE_PBX_DONT; /* don't try again */
 
2693
                cc_log(LOG_NOTICE, "%s: did not find exten for '%s', ignoring call.\n",
 
2694
                        i->vname, i->dnid);
 
2695
                CONNECT_RESP_HEADER(&CMSG2, capi_ApplID, MessageNumber, 0);
 
2696
                CONNECT_RESP_PLCI(&CMSG2) = PLCI;
 
2697
                CONNECT_RESP_REJECT(&CMSG2) = 1; /* ignore */
 
2698
                _capi_put_cmsg(&CMSG2);
 
2699
        }
 
2700
        return;
 
2701
}
 
2702
 
 
2703
/*
 
2704
 * Called Party Number via INFO_IND
 
2705
 */
 
2706
static void capidev_handle_did_digits(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt *i)
 
2707
{
 
2708
        char *did;
 
2709
        struct ast_frame fr = { AST_FRAME_NULL, };
 
2710
        int a;
 
2711
 
 
2712
        if (!i->owner) {
 
2713
                cc_log(LOG_ERROR, "No channel for interface!\n");
 
2714
                return;
 
2715
        }
 
2716
 
 
2717
        if (i->state != CAPI_STATE_DID) {
 
2718
                cc_verbose(4, 1, VERBOSE_PREFIX_4 "%s: INFO_IND DID digits not used in this state.\n",
 
2719
                        i->vname);
 
2720
                return;
 
2721
        }
 
2722
 
 
2723
        did = capi_number(INFO_IND_INFOELEMENT(CMSG), 1);
 
2724
 
 
2725
        if ((!(i->isdnstate & CAPI_ISDN_STATE_DID)) && 
 
2726
            (strlen(i->dnid) && !strcasecmp(i->dnid, did))) {
 
2727
                did = NULL;
 
2728
        }
 
2729
 
 
2730
        if ((did) && (strlen(i->dnid) < (sizeof(i->dnid) - 1)))
 
2731
                strcat(i->dnid, did);
 
2732
 
 
2733
        i->isdnstate |= CAPI_ISDN_STATE_DID;
 
2734
        
 
2735
        update_channel_name(i); 
 
2736
        
 
2737
        if (i->owner->pbx != NULL) {
 
2738
                /* we are already in pbx, so we send the digits as dtmf */
 
2739
                for (a = 0; a < strlen(did); a++) {
 
2740
                        fr.frametype = AST_FRAME_DTMF;
 
2741
                        fr.subclass = did[a];
 
2742
                        local_queue_frame(i, &fr);
 
2743
                } 
 
2744
                return;
 
2745
        }
 
2746
 
 
2747
        start_pbx_on_match(i, PLCI, HEADER_MSGNUM(CMSG));
 
2748
        return;
 
2749
}
 
2750
 
 
2751
/*
 
2752
 * send control according to cause code
 
2753
 */
 
2754
static void queue_cause_control(struct capi_pvt *i, int control)
 
2755
{
 
2756
        struct ast_frame fr = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP, };
 
2757
        
 
2758
        if ((i->owner) && (control)) {
 
2759
                int cause = i->owner->hangupcause;
 
2760
                if (cause == AST_CAUSE_NORMAL_CIRCUIT_CONGESTION) {
 
2761
                        fr.subclass = AST_CONTROL_CONGESTION;
 
2762
                } else if ((cause != AST_CAUSE_NO_USER_RESPONSE) &&
 
2763
                           (cause != AST_CAUSE_NO_ANSWER)) {
 
2764
                        /* not NOANSWER */
 
2765
                        fr.subclass = AST_CONTROL_BUSY;
 
2766
                }
 
2767
        }
 
2768
        local_queue_frame(i, &fr);
 
2769
        return;
 
2770
}
 
2771
 
 
2772
/*
 
2773
 * Disconnect via INFO_IND
 
2774
 */
 
2775
static void capidev_handle_info_disconnect(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt *i)
 
2776
{
 
2777
        _cmsg CMSG2;
 
2778
 
 
2779
        i->isdnstate |= CAPI_ISDN_STATE_DISCONNECT;
 
2780
 
 
2781
        if ((i->isdnstate & CAPI_ISDN_STATE_ECT)) {
 
2782
                cc_verbose(4, 1, VERBOSE_PREFIX_3 "%s: Disconnect ECT call\n",
 
2783
                        i->vname);
 
2784
                /* we do nothing, just wait for DISCONNECT_IND */
 
2785
                return;
 
2786
        }
 
2787
 
 
2788
        if (PLCI == i->onholdPLCI) {
 
2789
                cc_verbose(4, 1, VERBOSE_PREFIX_3 "%s: Disconnect onhold call\n",
 
2790
                        i->vname);
 
2791
                /* the caller onhold hung up (or ECTed away) */
 
2792
                /* send a disconnect_req , we cannot hangup the channel here!!! */
 
2793
                DISCONNECT_REQ_HEADER(&CMSG2, capi_ApplID, get_capi_MessageNumber(), 0);
 
2794
                DISCONNECT_REQ_PLCI(&CMSG2) = i->onholdPLCI;
 
2795
                _capi_put_cmsg(&CMSG2);
 
2796
                return;
 
2797
        }
 
2798
 
 
2799
        /* case 1: B3 on success or no B3 at all */
 
2800
        if ((i->doB3 != CAPI_B3_ALWAYS) && (i->outgoing == 1)) {
 
2801
                cc_verbose(4, 1, VERBOSE_PREFIX_3 "%s: Disconnect case 1\n",
 
2802
                        i->vname);
 
2803
                if (i->state == CAPI_STATE_CONNECTED) 
 
2804
                        queue_cause_control(i, 0);
 
2805
                else
 
2806
                        queue_cause_control(i, 1);
 
2807
                return;
 
2808
        }
 
2809
        
 
2810
        /* case 2: we are doing B3, and receive the 0x8045 after a successful call */
 
2811
        if ((i->doB3 != CAPI_B3_DONT) &&
 
2812
            (i->state == CAPI_STATE_CONNECTED) && (i->outgoing == 1)) {
 
2813
                cc_verbose(4, 1, VERBOSE_PREFIX_3 "%s: Disconnect case 2\n",
 
2814
                        i->vname);
 
2815
                queue_cause_control(i, 1);
 
2816
                return;
 
2817
        }
 
2818
 
 
2819
        /*
 
2820
         * case 3: this channel is an incoming channel! the user hung up!
 
2821
         * it is much better to hangup now instead of waiting for a timeout and
 
2822
         * network caused DISCONNECT_IND!
 
2823
         */
 
2824
        if (i->outgoing == 0) {
 
2825
                cc_verbose(4, 1, VERBOSE_PREFIX_3 "%s: Disconnect case 3\n",
 
2826
                        i->vname);
 
2827
                if (i->FaxState & CAPI_FAX_STATE_ACTIVE) {
 
2828
                        /* in fax mode, we just hangup */
 
2829
                        DISCONNECT_REQ_HEADER(&CMSG2, capi_ApplID, get_capi_MessageNumber(), 0);
 
2830
                        DISCONNECT_REQ_PLCI(&CMSG2) = i->PLCI;
 
2831
                        _capi_put_cmsg(&CMSG2);
 
2832
                        return;
 
2833
                }
 
2834
                queue_cause_control(i, 0);
 
2835
                return;
 
2836
        }
 
2837
        
 
2838
        /* case 4 (a.k.a. the italian case): B3 always. call is unsuccessful */
 
2839
        if ((i->doB3 == CAPI_B3_ALWAYS) && (i->outgoing == 1)) {
 
2840
                cc_verbose(4, 1, VERBOSE_PREFIX_3 "%s: Disconnect case 4\n",
 
2841
                        i->vname);
 
2842
                if ((i->state == CAPI_STATE_CONNECTED) &&
 
2843
                    (i->isdnstate & CAPI_ISDN_STATE_B3_UP)) {
 
2844
                        queue_cause_control(i, 1);
 
2845
                        return;
 
2846
                }
 
2847
                /* wait for the 0x001e (PROGRESS), play audio and wait for a timeout from the network */
 
2848
                return;
 
2849
        }
 
2850
        cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: Other case DISCONNECT INFO_IND\n",
 
2851
                i->vname);
 
2852
        return;
 
2853
}
 
2854
 
 
2855
/*
 
2856
 * incoming call SETUP
 
2857
 */
 
2858
static void capidev_handle_setup_element(_cmsg *CMSG, unsigned int PLCI, struct capi_pvt *i)
 
2859
{
 
2860
        if ((i->isdnstate & CAPI_ISDN_STATE_SETUP)) {
 
2861
                cc_verbose(3, 1, VERBOSE_PREFIX_4 "%s: IE SETUP / SENDING-COMPLETE already received.\n",
 
2862
                        i->vname);
 
2863
                return;
 
2864
        }
 
2865
 
 
2866
        i->isdnstate |= CAPI_ISDN_STATE_SETUP;
 
2867
 
 
2868
        if (!i->owner) {
 
2869
                cc_log(LOG_ERROR, "No channel for interface!\n");
 
2870
                return;
 
2871
        }
 
2872
 
 
2873
        if (i->isdnmode == CAPI_ISDNMODE_DID) {
 
2874
                if (!strlen(i->dnid) && (i->immediate)) {
 
2875
                        start_pbx_on_match(i, PLCI, HEADER_MSGNUM(CMSG));
 
2876
                }
 
2877
        } else {
 
2878
                start_pbx_on_match(i, PLCI, HEADER_MSGNUM(CMSG));
 
2879
        }
 
2880
        return;
 
2881
}
 
2882
 
 
2883
/*
 
2884
 * CAPI INFO_IND
 
2885
 */
 
2886
static void capidev_handle_info_indication(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt *i)
 
2887
{
 
2888
        _cmsg CMSG2;
 
2889
        struct ast_frame fr = { AST_FRAME_NULL, };
 
2890
        char *p = NULL;
 
2891
        int val = 0;
 
2892
 
 
2893
        INFO_RESP_HEADER(&CMSG2, capi_ApplID, HEADER_MSGNUM(CMSG), PLCI);
 
2894
        _capi_put_cmsg(&CMSG2);
 
2895
 
 
2896
        return_on_no_interface("INFO_IND");
 
2897
 
 
2898
        switch(INFO_IND_INFONUMBER(CMSG)) {
 
2899
        case 0x0008:    /* Cause */
 
2900
                cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element CAUSE %02x %02x\n",
 
2901
                        i->vname, INFO_IND_INFOELEMENT(CMSG)[1], INFO_IND_INFOELEMENT(CMSG)[2]);
 
2902
                if (i->owner) {
 
2903
                        i->owner->hangupcause = INFO_IND_INFOELEMENT(CMSG)[2] & 0x7f;
 
2904
                }
 
2905
                break;
 
2906
        case 0x0014:    /* Call State */
 
2907
                cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element CALL STATE %02x\n",
 
2908
                        i->vname, INFO_IND_INFOELEMENT(CMSG)[1]);
 
2909
                break;
 
2910
        case 0x0018:    /* Channel Identification */
 
2911
                cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element CHANNEL IDENTIFICATION %02x\n",
 
2912
                        i->vname, INFO_IND_INFOELEMENT(CMSG)[1]);
 
2913
                break;
 
2914
        case 0x001c:    /*  Facility Q.932 */
 
2915
                cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element FACILITY\n",
 
2916
                        i->vname);
 
2917
                break;
 
2918
        case 0x001e:    /* Progress Indicator */
 
2919
                cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element PI %02x %02x\n",
 
2920
                        i->vname, INFO_IND_INFOELEMENT(CMSG)[1], INFO_IND_INFOELEMENT(CMSG)[2]);
 
2921
                handle_progress_indicator(CMSG, PLCI, i);
 
2922
                break;
 
2923
        case 0x0027: {  /*  Notification Indicator */
 
2924
                char *desc = "?";
 
2925
                if (INFO_IND_INFOELEMENT(CMSG)[0] > 0) {
 
2926
                        switch (INFO_IND_INFOELEMENT(CMSG)[1]) {
 
2927
                        case 0:
 
2928
                                desc = "User suspended";
 
2929
                                break;
 
2930
                        case 1:
 
2931
                                desc = "User resumed";
 
2932
                                break;
 
2933
                        case 2:
 
2934
                                desc = "Bearer service changed";
 
2935
                                break;
 
2936
                        case 0xf9:
 
2937
                                desc = "User put on hold";
 
2938
                                break;
 
2939
                        case 0xfa:
 
2940
                                desc = "User retrieved from hold";
 
2941
                                break;
 
2942
                        }
 
2943
                }
 
2944
                cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element NOTIFICATION INDICATOR '%s' (0x%02x)\n",
 
2945
                        i->vname, desc, INFO_IND_INFOELEMENT(CMSG)[1]);
 
2946
                break;
 
2947
        }
 
2948
        case 0x0028:    /* DSP */
 
2949
                cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element DSP\n",
 
2950
                        i->vname);
 
2951
                break;
 
2952
        case 0x0029:    /* Date/Time */
 
2953
                cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element Date/Time %02d/%02d/%02d %02d:%02d\n",
 
2954
                        i->vname,
 
2955
                        INFO_IND_INFOELEMENT(CMSG)[1], INFO_IND_INFOELEMENT(CMSG)[2],
 
2956
                        INFO_IND_INFOELEMENT(CMSG)[3], INFO_IND_INFOELEMENT(CMSG)[4],
 
2957
                        INFO_IND_INFOELEMENT(CMSG)[5]);
 
2958
                break;
 
2959
        case 0x0070:    /* Called Party Number */
 
2960
                cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element CALLED PARTY NUMBER\n",
 
2961
                        i->vname);
 
2962
                capidev_handle_did_digits(CMSG, PLCI, NCCI, i);
 
2963
                break;
 
2964
        case 0x0074:    /* Redirecting Number */
 
2965
                p = capi_number(INFO_IND_INFOELEMENT(CMSG), 3);
 
2966
                if (INFO_IND_INFOELEMENT(CMSG)[0] > 2) {
 
2967
                        val = INFO_IND_INFOELEMENT(CMSG)[3] & 0x0f;
 
2968
                }
 
2969
                cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element REDIRECTING NUMBER '%s' Reason=0x%02x\n",
 
2970
                        i->vname, p, val);
 
2971
                if (i->owner) {
 
2972
                        char reasonbuf[16];
 
2973
                        snprintf(reasonbuf, sizeof(reasonbuf) - 1, "%d", val); 
 
2974
                        pbx_builtin_setvar_helper(i->owner, "REDIRECTINGNUMBER", p);
 
2975
                        pbx_builtin_setvar_helper(i->owner, "REDIRECTREASON", reasonbuf);
 
2976
                        if (i->owner->cid.cid_rdnis) {
 
2977
                                free(i->owner->cid.cid_rdnis);
 
2978
                        }
 
2979
                        i->owner->cid.cid_rdnis = strdup(p);
 
2980
                }
 
2981
                break;
 
2982
        case 0x00a1:    /* Sending Complete */
 
2983
                cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element Sending Complete\n",
 
2984
                        i->vname);
 
2985
                capidev_handle_setup_element(CMSG, PLCI, i);
 
2986
                break;
 
2987
        case 0x4000:    /* CHARGE in UNITS */
 
2988
                cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element CHARGE in UNITS\n",
 
2989
                        i->vname);
 
2990
                break;
 
2991
        case 0x4001:    /* CHARGE in CURRENCY */
 
2992
                cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element CHARGE in CURRENCY\n",
 
2993
                        i->vname);
 
2994
                break;
 
2995
        case 0x8001:    /* ALERTING */
 
2996
                cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element ALERTING\n",
 
2997
                        i->vname);
 
2998
                send_progress(i);
 
2999
                fr.frametype = AST_FRAME_CONTROL;
 
3000
                fr.subclass = AST_CONTROL_RINGING;
 
3001
                local_queue_frame(i, &fr);
 
3002
                if (i->owner)
 
3003
                        ast_setstate(i->owner, AST_STATE_RINGING);
 
3004
                break;
 
3005
        case 0x8002:    /* CALL PROCEEDING */
 
3006
                cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element CALL PROCEEDING\n",
 
3007
                        i->vname);
 
3008
                fr.frametype = AST_FRAME_CONTROL;
 
3009
                fr.subclass = AST_CONTROL_PROCEEDING;
 
3010
                local_queue_frame(i, &fr);
 
3011
                break;
 
3012
        case 0x8003:    /* PROGRESS */
 
3013
                cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element PROGRESS\n",
 
3014
                        i->vname);
 
3015
                /*
 
3016
                 * rain - some networks will indicate a USER BUSY cause, send
 
3017
                 * PROGRESS message, and then send audio for a busy signal for
 
3018
                 * a moment before dropping the line.  This delays sending the
 
3019
                 * busy to the end user, so we explicitly check for it here.
 
3020
                 *
 
3021
                 * FIXME: should have better CAUSE handling so that we can
 
3022
                 * distinguish things like status responses and invalid IE
 
3023
                 * content messages (from bad SetCallerID) from errors actually
 
3024
                 * related to the call setup; then, we could always abort if we
 
3025
                 * get a PROGRESS with a hangupcause set (safer?)
 
3026
                 */
 
3027
                if (i->doB3 == CAPI_B3_DONT) {
 
3028
                        if ((i->owner) &&
 
3029
                            (i->owner->hangupcause == AST_CAUSE_USER_BUSY)) {
 
3030
                                queue_cause_control(i, 1);
 
3031
                                break;
 
3032
                        }
 
3033
                }
 
3034
                send_progress(i);
 
3035
                break;
 
3036
        case 0x8005:    /* SETUP */
 
3037
                cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element SETUP\n",
 
3038
                        i->vname);
 
3039
                capidev_handle_setup_element(CMSG, PLCI, i);
 
3040
                break;
 
3041
        case 0x8007:    /* CONNECT */
 
3042
                cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element CONNECT\n",
 
3043
                        i->vname);
 
3044
                break;
 
3045
        case 0x800d:    /* SETUP ACK */
 
3046
                cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element SETUP ACK\n",
 
3047
                        i->vname);
 
3048
                i->isdnstate |= CAPI_ISDN_STATE_SETUP_ACK;
 
3049
                /* if some digits of initial CONNECT_REQ are left to dial */
 
3050
                if (strlen(i->overlapdigits)) {
 
3051
                        capi_send_info_digits(i, i->overlapdigits,
 
3052
                                strlen(i->overlapdigits));
 
3053
                        i->overlapdigits[0] = 0;
 
3054
                        i->doOverlap = 0;
 
3055
                }
 
3056
                break;
 
3057
        case 0x800f:    /* CONNECT ACK */
 
3058
                cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element CONNECT ACK\n",
 
3059
                        i->vname);
 
3060
                break;
 
3061
        case 0x8045:    /* DISCONNECT */
 
3062
                cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element DISCONNECT\n",
 
3063
                        i->vname);
 
3064
                capidev_handle_info_disconnect(CMSG, PLCI, NCCI, i);
 
3065
                break;
 
3066
        case 0x804d:    /* RELEASE */
 
3067
                cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element RELEASE\n",
 
3068
                        i->vname);
 
3069
                break;
 
3070
        case 0x805a:    /* RELEASE COMPLETE */
 
3071
                cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element RELEASE COMPLETE\n",
 
3072
                        i->vname);
 
3073
                break;
 
3074
        case 0x8062:    /* FACILITY */
 
3075
                cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element FACILITY\n",
 
3076
                        i->vname);
 
3077
                break;
 
3078
        case 0x806e:    /* NOTIFY */
 
3079
                cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element NOTIFY\n",
 
3080
                        i->vname);
 
3081
                break;
 
3082
        case 0x807b:    /* INFORMATION */
 
3083
                cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element INFORMATION\n",
 
3084
                        i->vname);
 
3085
                break;
 
3086
        case 0x807d:    /* STATUS */
 
3087
                cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element STATUS\n",
 
3088
                        i->vname);
 
3089
                break;
 
3090
        default:
 
3091
                cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: unhandled INFO_IND %#x (PLCI=%#x)\n",
 
3092
                        i->vname, INFO_IND_INFONUMBER(CMSG), PLCI);
 
3093
                break;
 
3094
        }
 
3095
        return;
 
3096
}
 
3097
 
 
3098
/*
 
3099
 * CAPI FACILITY_IND
 
3100
 */
 
3101
static void capidev_handle_facility_indication(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt *i)
 
3102
{
 
3103
        _cmsg CMSG2;
 
3104
        struct ast_frame fr = { AST_FRAME_NULL, };
1279
3105
        char dtmf;
1280
3106
        unsigned dtmflen;
1281
 
#ifdef CAPI_ES
 
3107
        unsigned dtmfpos = 0;
 
3108
 
 
3109
        FACILITY_RESP_HEADER(&CMSG2, capi_ApplID, HEADER_MSGNUM(CMSG), PLCI);
 
3110
        FACILITY_RESP_FACILITYSELECTOR(&CMSG2) = FACILITY_IND_FACILITYSELECTOR(CMSG);
 
3111
        FACILITY_RESP_FACILITYRESPONSEPARAMETERS(&CMSG2) = FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG);
 
3112
        _capi_put_cmsg(&CMSG2);
 
3113
        
 
3114
        return_on_no_interface("FACILITY_IND");
 
3115
 
 
3116
        if (FACILITY_IND_FACILITYSELECTOR(CMSG) == FACILITYSELECTOR_LINE_INTERCONNECT) {
 
3117
                /* line interconnect */
 
3118
                if ((FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[1] == 0x01) &&
 
3119
                    (FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[2] == 0x00)) {
 
3120
                        cc_verbose(3, 0, VERBOSE_PREFIX_3 "%s: Line Interconnect activated\n",
 
3121
                                i->vname);
 
3122
                }
 
3123
                if ((FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[1] == 0x02) &&
 
3124
                    (FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[2] == 0x00) &&
 
3125
                    (FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[0] > 8)) {
 
3126
                        show_capi_info(i, read_capi_word(&FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[8]));
 
3127
                }
 
3128
        }
 
3129
        
 
3130
        if (FACILITY_IND_FACILITYSELECTOR(CMSG) == FACILITYSELECTOR_DTMF) {
 
3131
                /* DTMF received */
 
3132
                if (FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[0] != (0xff)) {
 
3133
                        dtmflen = FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[0];
 
3134
                        FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG) += 1;
 
3135
                } else {
 
3136
                        dtmflen = read_capi_word(FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG) + 1);
 
3137
                        FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG) += 3;
 
3138
                }
 
3139
                while (dtmflen) {
 
3140
                        dtmf = (FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG))[dtmfpos];
 
3141
                        cc_verbose(1, 1, VERBOSE_PREFIX_4 "%s: c_dtmf = %c\n",
 
3142
                                i->vname, dtmf);
 
3143
                        if ((!(i->ntmode)) || (i->state == CAPI_STATE_CONNECTED)) {
 
3144
                                if ((dtmf == 'X') || (dtmf == 'Y')) {
 
3145
                                        capi_handle_dtmf_fax(i);
 
3146
                                } else {
 
3147
                                        fr.frametype = AST_FRAME_DTMF;
 
3148
                                        fr.subclass = dtmf;
 
3149
                                        local_queue_frame(i, &fr);
 
3150
                                }
 
3151
                        }
 
3152
                        dtmflen--;
 
3153
                        dtmfpos++;
 
3154
                } 
 
3155
        }
 
3156
        
 
3157
        if (FACILITY_IND_FACILITYSELECTOR(CMSG) == FACILITYSELECTOR_SUPPLEMENTARY) {
 
3158
                /* supplementary sservices */
 
3159
                /* ECT */
 
3160
                if ( (FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[1] == 0x6) &&
 
3161
                     (FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[3] == 0x2) ) {
 
3162
                        cc_verbose(1, 1, VERBOSE_PREFIX_3 "%s: PLCI=%#x ECT  Reason=0x%02x%02x\n",
 
3163
                                i->vname, PLCI,
 
3164
                                FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[5],
 
3165
                                FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[4]);
 
3166
                        show_capi_info(i, read_capi_word(&FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[4]));
 
3167
                }
 
3168
 
 
3169
                /* RETRIEVE */
 
3170
                if ( (FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[1] == 0x3) &&
 
3171
                     (FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[3] == 0x2) ) {
 
3172
                        if ((FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[5] != 0) || 
 
3173
                            (FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[4] != 0)) { 
 
3174
                                cc_log(LOG_WARNING, "%s: unable to retrieve PLCI=%#x, REASON = 0x%02x%02x\n",
 
3175
                                        i->vname, PLCI,
 
3176
                                        FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[5],
 
3177
                                        FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[4]);
 
3178
                                show_capi_info(i, read_capi_word(&FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[4]));
 
3179
                        } else {
 
3180
                                /* reason != 0x0000 == problem */
 
3181
                                i->state = CAPI_STATE_CONNECTED;
 
3182
                                i->PLCI = i->onholdPLCI;
 
3183
                                i->onholdPLCI = 0;
 
3184
                                cc_verbose(1, 1, VERBOSE_PREFIX_3 "%s: PLCI=%#x retrieved\n",
 
3185
                                        i->vname, PLCI);
 
3186
                                cc_start_b3(i);
 
3187
                        }
 
3188
                }
 
3189
                
 
3190
                /* HOLD */
 
3191
                if ( (FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[1] == 0x2) &&
 
3192
                     (FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[3] == 0x2) ) {
 
3193
                        if ((FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[5] != 0) || 
 
3194
                            (FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[4] != 0)) { 
 
3195
                                /* reason != 0x0000 == problem */
 
3196
                                i->onholdPLCI = 0;
 
3197
                                cc_log(LOG_WARNING, "%s: unable to put PLCI=%#x onhold, REASON = 0x%02x%02x, maybe you need to subscribe for this...\n",
 
3198
                                        i->vname, PLCI,
 
3199
                                        FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[5],
 
3200
                                        FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[4]);
 
3201
                                show_capi_info(i, read_capi_word(&FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[4]));
 
3202
                        } else {
 
3203
                                /* reason = 0x0000 == call on hold */
 
3204
                                i->state = CAPI_STATE_ONHOLD;
 
3205
                                cc_verbose(1, 1, VERBOSE_PREFIX_3 "%s: PLCI=%#x put onhold\n",
 
3206
                                        i->vname, PLCI);
 
3207
                        }
 
3208
                }
 
3209
        }
 
3210
        return;
 
3211
}
 
3212
 
 
3213
/*
 
3214
 * CAPI DATA_B3_IND
 
3215
 */
 
3216
static void capidev_handle_data_b3_indication(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt *i)
 
3217
{
 
3218
        _cmsg CMSG2;
 
3219
        struct ast_frame fr = { AST_FRAME_NULL, };
 
3220
        unsigned char *b3buf = NULL;
 
3221
        int b3len = 0;
 
3222
        int j;
1282
3223
        int rxavg = 0;
1283
3224
        int txavg = 0;
1284
 
#endif    
1285
 
 
1286
 
        p = find_pipe(PLCI,CMSG->Messagenumber);
1287
 
        if (p == NULL) {
1288
 
            if (IS_DISCONNECT_IND(CMSG)) {
1289
 
                DISCONNECT_RESP_HEADER(&CMSG2, ast_capi_ApplID, CMSG->Messagenumber , 0);
1290
 
                DISCONNECT_RESP_PLCI(&CMSG2) = PLCI;
1291
 
                if ((error = _capi_put_cmsg(&CMSG2)) != 0) {
1292
 
                    ast_log(LOG_NOTICE, "error sending DISCONNECT_RESP PLCI=%#x\n",PLCI);
1293
 
                } else {
1294
 
                    if (option_verbose > 5) {
1295
 
                        if (capidebug)
1296
 
                            ast_verbose(VERBOSE_PREFIX_4 "sent DISCONNECT_RESP PLCI=%#x\n",PLCI);
1297
 
                    }
1298
 
                }           
1299
 
                return 0;
1300
 
            }
1301
 
            if (capidebug) {
1302
 
                ast_log(LOG_NOTICE,"%s",capi_cmsg2str(CMSG));
1303
 
            }
1304
 
            return -1;
1305
 
        }
1306
 
 
1307
 
        if (CMSG != NULL) {
1308
 
            switch (CMSG->Subcommand) {
1309
 
                case CAPI_IND:
1310
 
                    switch (CMSG->Command) {
1311
 
                        case CAPI_DISCONNECT_B3:
1312
 
//                          ast_log(LOG_NOTICE,"DISCONNECT_B3_IND\n");
1313
 
 
1314
 
                            DISCONNECT_B3_RESP_HEADER(&CMSG2, ast_capi_ApplID, CMSG->Messagenumber, 0);
1315
 
                            DISCONNECT_B3_RESP_NCCI(&CMSG2) = DISCONNECT_B3_IND_NCCI(CMSG);
1316
 
 
1317
 
                            if ((error = _capi_put_cmsg(&CMSG2)) != 0) {
1318
 
                                ast_log(LOG_NOTICE, "error sending DISCONNECT_B3_RESP NCCI=%#x\n",(int)DISCONNECT_B3_IND_NCCI(CMSG));
1319
 
                            } else {
1320
 
                                if (option_verbose > 5) {
1321
 
                                    if (capidebug)
1322
 
                                        ast_verbose(VERBOSE_PREFIX_4 "sent DISCONNECT_B3_RESP NCCI=%#x\n",(int)DISCONNECT_B3_IND_NCCI(CMSG));
1323
 
                                }
1324
 
                            }
1325
 
                            if (p->i->state == CAPI_STATE_BCONNECTED) {
1326
 
                                // passive disconnect
1327
 
                                p->i->state = CAPI_STATE_CONNECTED;
1328
 
                            } else
1329
 
                            if (p->i->state == CAPI_STATE_DISCONNECTING) {
1330
 
                                // active disconnect
1331
 
                                memset(&CMSG2,0,sizeof(_cmsg));
1332
 
                                DISCONNECT_REQ_HEADER(&CMSG2, ast_capi_ApplID, ast_capi_MessageNumber++, 0);
1333
 
                                DISCONNECT_REQ_PLCI(&CMSG2) = PLCI;
1334
 
 
1335
 
                                if ((error = _capi_put_cmsg(&CMSG2)) != 0) {
1336
 
                                    ast_log(LOG_NOTICE, "error sending DISCONNECT_REQ PLCI=%#x\n",PLCI);
1337
 
                                } else {
1338
 
                                    if (option_verbose > 5) {
1339
 
                                        if (capidebug)
1340
 
                                            ast_verbose(VERBOSE_PREFIX_4 "sent DISCONNECT_REQ PLCI=%#x\n",PLCI);
1341
 
                                    }
1342
 
                                }                               
1343
 
                            } else 
1344
 
                            if (p->i->state == CAPI_STATE_ONHOLD) {
1345
 
                                    // no hangup
1346
 
                            }
1347
 
                            ast_mutex_lock(&contrlock);
1348
 
                            if (p->i->controller > 0) {
1349
 
                                capi_controllers[p->i->controller]->nfreebchannels++;
1350
 
                            }
1351
 
                            ast_mutex_unlock(&contrlock);
1352
 
                            break;
1353
 
                        case CAPI_DISCONNECT:
1354
 
//                          ast_log(LOG_NOTICE,"DISCONNECT_IND\n");
1355
 
                            DISCONNECT_RESP_HEADER(&CMSG2, ast_capi_ApplID, CMSG->Messagenumber , 0);
1356
 
                            DISCONNECT_RESP_PLCI(&CMSG2) = PLCI;
1357
 
/*                          if (p->i->controller > 0) {
1358
 
                                capi_controllers[p->i->controller]->nfreebchannels++;
1359
 
                            } */
1360
 
 
1361
 
                            if ((error = _capi_put_cmsg(&CMSG2)) != 0) {
1362
 
                                ast_log(LOG_NOTICE, "error sending DISCONNECT_RESP PLCI=%#x\n",PLCI);
1363
 
                            } else {
1364
 
                                if (option_verbose > 5) {
1365
 
                                    if (capidebug)
1366
 
                                        ast_verbose(VERBOSE_PREFIX_4 "sent DISCONNECT_RESP PLCI=%#x\n",PLCI);
1367
 
                                }
1368
 
                            }
1369
 
                            
1370
 
                            if (PLCI == p->i->onholdPLCI) {
1371
 
                                // the caller onhold hung up (or ECTed away)
1372
 
                                p->i->onholdPLCI = 0;
1373
 
                                remove_pipe(PLCI);
1374
 
                                return 0;
1375
 
                            }
1376
 
                            
1377
 
                            if (p->i->state == CAPI_STATE_DID) {
1378
 
                                if ((p->c) != NULL) {
1379
 
                                    ast_hangup(p->c);
1380
 
                                } else {    
1381
 
                                    ast_log(LOG_WARNING, "unable to hangup channel on DID. Channel is NULL.\n");
1382
 
                                }
1383
 
                                return 0;                               
1384
 
                            }
1385
 
                            
1386
 
                            p->i->state = CAPI_STATE_DISCONNECTED;
1387
 
 
1388
 
                            fr.frametype = AST_FRAME_CONTROL;
1389
 
                            if (DISCONNECT_IND_REASON(CMSG) == 0x34a2) {
1390
 
                                fr.subclass = AST_CONTROL_BUSY;
1391
 
                            } else {
1392
 
                                fr.frametype = AST_FRAME_NULL;
1393
 
                            }
1394
 
                            fr.datalen = 0;
1395
 
                            if (pipe_frame(p,(struct ast_frame *)&fr) == -1) {
1396
 
                // printf("STATE = %#x\n",p->i->state);
1397
 
                                // in this case * did not read our hangup control frame
1398
 
                                // so we must hangup the channel!
1399
 
                                if ( (p->i->state != CAPI_STATE_DISCONNECTED) && (ast_check_hangup(p->c) == 0)) {
1400
 
                                    if (option_verbose > 1) {
1401
 
                                        ast_verbose(VERBOSE_PREFIX_3 "soft hangup by capi\n");
1402
 
                                    }
1403
 
                                    ast_softhangup(p->c,AST_CONTROL_HANGUP);
1404
 
                                } else {
1405
 
                                    // dont ever hangup while hanging up!
1406
 
//                                  ast_log(LOG_NOTICE,"no soft hangup by capi\n");
1407
 
                                }
1408
 
                                return -1;
1409
 
                            } else {
1410
 
                                return 0;
1411
 
                            }
1412
 
 
1413
 
/*                          fr.frametype = AST_FRAME_NULL;
1414
 
                            fr.datalen = 0;
1415
 
                            pipe_frame(p,(struct ast_frame *)&fr); */
1416
 
                            break;
1417
 
                        case CAPI_DATA_B3:
1418
 
 
1419
 
                            memcpy(&b3buf[AST_FRIENDLY_OFFSET],(char *)DATA_B3_IND_DATA(CMSG),DATA_B3_IND_DATALENGTH(CMSG));
1420
 
                            b3len = DATA_B3_IND_DATALENGTH(CMSG);
1421
 
                        
1422
 
                            // send a DATA_B3_RESP very quickly to free the buffer in capi
1423
 
                            DATA_B3_RESP_HEADER(&CMSG2, ast_capi_ApplID, CMSG->Messagenumber,0);
1424
 
                            DATA_B3_RESP_NCCI(&CMSG2) = DATA_B3_IND_NCCI(CMSG);
1425
 
                            DATA_B3_RESP_DATAHANDLE(&CMSG2) = DATA_B3_IND_DATAHANDLE(CMSG);
1426
 
                            if ((error = _capi_put_cmsg(&CMSG2)) != 0) {
1427
 
                                ast_log(LOG_ERROR,"error sending DATA_B3_RESP (error=%#x)\n",error);
1428
 
                            } else {
1429
 
                                if (option_verbose > 6) {
1430
 
                                    if (capidebug)
1431
 
                                        ast_verbose(VERBOSE_PREFIX_4 "sent DATA_B3_RESP (NCCI=%#x)\n",(int)DATA_B3_IND_NCCI(CMSG));
1432
 
                                }
1433
 
                            }
1434
 
#ifdef CAPI_SYNC
1435
 
                            ast_mutex_lock(&p->i->lockB3in);
1436
 
                            p->i->B3in++;
1437
 
                            if (p->i->B3in > AST_CAPI_MAX_B3_BLOCKS) p->i->B3in = AST_CAPI_MAX_B3_BLOCKS;
1438
 
                            ast_mutex_unlock(&p->i->lockB3in);
1439
 
#endif                      
1440
 
#ifdef CAPI_ES
1441
 
                            if ((p->i->doES == 1)) {
1442
 
                                for (j=0;j<b3len;j++) {
1443
 
                                    b3buf[AST_FRIENDLY_OFFSET + j] = reversebits[(unsigned char)b3buf[AST_FRIENDLY_OFFSET + j]]; 
1444
 
                                    rxavg += abs(capiXLAW2INT( reversebits[(unsigned char)b3buf[AST_FRIENDLY_OFFSET + j]]));
1445
 
                                }
1446
 
                                rxavg = rxavg/j;
1447
 
                                for(j=0;j<ECHO_EFFECTIVE_TX_COUNT;j++) {
1448
 
                                    txavg += p->i->txavg[j];
1449
 
                                }
1450
 
                                txavg = txavg/j;
1451
 
                            
1452
 
                                if( (txavg/ECHO_TXRX_RATIO) > rxavg) { 
1453
 
#ifdef CAPI_ULAW
1454
 
                                    memset(&b3buf[AST_FRIENDLY_OFFSET],255,b3len);
1455
 
#else
1456
 
                                    memset(&b3buf[AST_FRIENDLY_OFFSET],84,b3len);
1457
 
#endif
1458
 
                                    if (capidebug) {
1459
 
                                        ast_log(LOG_NOTICE,"SUPPRESSING ECHOrx=%d, tx=%d\n",rxavg,txavg);
1460
 
                                    }
1461
 
                                }
1462
 
                            } else {
1463
 
#ifdef CAPI_GAIN
1464
 
                                for (j=0;j<b3len;j++) {
1465
 
                                    b3buf[AST_FRIENDLY_OFFSET + j] = reversebits[p->i->g.rxgains[(unsigned char)b3buf[AST_FRIENDLY_OFFSET + j]]]; 
1466
 
                                }
1467
 
#else
1468
 
                                for (j=0;j<b3len;j++) {
1469
 
                                    b3buf[AST_FRIENDLY_OFFSET + j] = reversebits[(unsigned char)b3buf[AST_FRIENDLY_OFFSET + j]]; 
1470
 
                                }
1471
 
#endif
1472
 
                            }
1473
 
#else
1474
 
 
1475
 
#ifdef CAPI_GAIN
1476
 
                            for (j=0;j<b3len;j++) {
1477
 
                                b3buf[AST_FRIENDLY_OFFSET + j] = reversebits[p->i->g.rxgains[(unsigned char)b3buf[AST_FRIENDLY_OFFSET + j]]]; 
1478
 
                            }
1479
 
#else
1480
 
                            for (j=0;j<b3len;j++) {
1481
 
                                b3buf[AST_FRIENDLY_OFFSET + j] = reversebits[(unsigned char)b3buf[AST_FRIENDLY_OFFSET + j]]; 
1482
 
                            }
1483
 
#endif
1484
 
 
1485
 
#endif
1486
 
                            // just being paranoid ...
1487
 
                /*          if (p->c->_state != AST_STATE_UP) {
1488
 
                                ast_setstate(p->c,AST_STATE_UP);
1489
 
                            } */
1490
 
                            
1491
 
                            fr.frametype = AST_FRAME_VOICE;
1492
 
                            fr.subclass = capi_capability;
1493
 
                            fr.data = (char *)&b3buf[AST_FRIENDLY_OFFSET];
1494
 
                            fr.datalen = b3len;
1495
 
                            fr.samples = b3len;
1496
 
                            fr.offset = AST_FRIENDLY_OFFSET;
1497
 
                            fr.mallocd = 0;
1498
 
#ifdef UNSTABLE_CVS
1499
 
                            fr.delivery.tv_sec = 0;
1500
 
                            fr.delivery.tv_usec = 0;
1501
 
#endif
1502
 
                            fr.src = NULL;
1503
 
                        //          ast_verbose(VERBOSE_PREFIX_3 "DATA_B3_IND (len=%d) fr.datalen=%d fr.subclass=%d\n",(int)DATA_B3_IND_DATALENGTH(CMSG),fr.datalen,fr.subclass);
1504
 
                            return pipe_frame(p,(struct ast_frame *)&fr);
1505
 
                            break;
1506
 
                        case CAPI_FACILITY:
1507
 
                            if (FACILITY_IND_FACILITYSELECTOR(CMSG) == 0x0001) {
1508
 
                        // DTMF received
1509
 
                                if (FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[0] != (0xff)) {
1510
 
                                    dtmflen = FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[0];
1511
 
                                    FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG) += 1;
1512
 
                                } else {
1513
 
                                    dtmflen = ((__u16 *) (FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG) + 1))[0];
1514
 
                                    FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG) += 3;
1515
 
                                }
1516
 
                                if (dtmflen == 1) {
1517
 
                                    dtmf = (FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG))[0];
1518
 
                                    fr.frametype = AST_FRAME_DTMF;
1519
 
                                    fr.subclass = dtmf;
1520
 
                                    if (option_verbose > 1) {
1521
 
                                        if (capidebug)
1522
 
                                            ast_verbose(VERBOSE_PREFIX_3 "c_dtmf = %c\n",dtmf);
1523
 
                                    }
1524
 
                                    pipe_frame(p,(struct ast_frame *)&fr);
1525
 
                                } 
1526
 
                            }
1527
 
                            if (FACILITY_IND_FACILITYSELECTOR(CMSG) == 0x0003) {
1528
 
                            // sservices
1529
 
                        /*       ast_log(LOG_NOTICE,"FACILITY_IND PLCI = %#x\n",(int)FACILITY_IND_PLCI(CMSG));
1530
 
                                 ast_log(LOG_NOTICE,"%#x\n",FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[0]);
1531
 
                                 ast_log(LOG_NOTICE,"%#x\n",FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[1]);
1532
 
                                 ast_log(LOG_NOTICE,"%#x\n",FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[2]);
1533
 
                                 ast_log(LOG_NOTICE,"%#x\n",FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[3]);
1534
 
                                 ast_log(LOG_NOTICE,"%#x\n",FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[4]);
1535
 
                                 ast_log(LOG_NOTICE,"%#x\n",FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[5]);  */
1536
 
                                // RETRIEVE
1537
 
                                if ( (FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[1] == 0x3) && (FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[3] == 0x2)) {
1538
 
                                    p->i->state = CAPI_STATE_CONNECTED;
1539
 
                                    p->i->PLCI = p->i->onholdPLCI;
1540
 
                                    p->i->onholdPLCI = 0;
1541
 
                                }
1542
 
                                if ( (FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[1] == 0x2) && (FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[3] == 0x2)) {
1543
 
                                    if ((FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[5] != 0) && (FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[4] != 0)) { 
1544
 
                                        // reason != 0x0000 == problem
1545
 
                                        p->i->onholdPLCI = 0;
1546
 
                                        p->i->state = CAPI_STATE_ONHOLD;
1547
 
                                        ast_log(LOG_WARNING, "unable to put PLCI=%#x onhold, REASON = %#x%#x, maybe you need to subscribe for this...\n",(int)FACILITY_IND_PLCI(CMSG),FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[5],FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[4]);
1548
 
                                    } else {
1549
 
                                        // reason = 0x0000 == call on hold
1550
 
                                        p->i->state = CAPI_STATE_ONHOLD;
1551
 
                                        if (capidebug) 
1552
 
                                            ast_log(LOG_NOTICE, "PLCI=%#x put onhold\n",(int)FACILITY_IND_PLCI(CMSG));
1553
 
                                    }
1554
 
                                }
1555
 
                            }
1556
 
                            
1557
 
                            error = FACILITY_RESP(&CMSG2, ast_capi_ApplID, CMSG->Messagenumber,FACILITY_IND_PLCI(CMSG),FACILITY_IND_FACILITYSELECTOR(CMSG),FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG));
1558
 
 
1559
 
                            if (error != 0) {
1560
 
                                ast_log(LOG_ERROR,"error sending FACILITY_RESP (error=%#x)\n",error);
1561
 
                            } else {
1562
 
                                if (option_verbose > 5) {
1563
 
                                    if (capidebug)
1564
 
                                        ast_verbose(VERBOSE_PREFIX_4 "sent FACILITY_RESP (PLCI=%#x)\n",(int)FACILITY_IND_PLCI(CMSG));
1565
 
                                }
1566
 
                            }
1567
 
                            break;
1568
 
                        case CAPI_INFO:
1569
 
                            // ast_log(LOG_ERROR,"INFO_IND PLCI=%#x INFO# = %#x\n",PLCI,INFO_IND_INFONUMBER(CMSG));
1570
 
 
1571
 
                            memset(&CMSG2,0,sizeof(_cmsg));
1572
 
                            error = INFO_RESP(&CMSG2,ast_capi_ApplID,CMSG->Messagenumber,PLCI);
1573
 
                            if (error != 0) {
1574
 
                                ast_log(LOG_ERROR,"error sending INFO_RESP (error=%#x)\n",error);
1575
 
                                return -1;
1576
 
                            } else {
1577
 
                                if (option_verbose > 5) {
1578
 
                                    if (capidebug)
1579
 
                                        ast_verbose(VERBOSE_PREFIX_4 "sent INFO_RESP (PLCI=%#x)\n",PLCI);
1580
 
                                }
1581
 
                            }
1582
 
/*                          if ((INFO_IND_INFONUMBER(CMSG) >> 8) == 0x00) {
1583
 
                                ast_log(LOG_ERROR,"%#x\n",INFO_IND_INFOELEMENT(CMSG)[0]);
1584
 
                                ast_log(LOG_ERROR,"%#x\n",INFO_IND_INFOELEMENT(CMSG)[1]);
1585
 
                                ast_log(LOG_ERROR,"%#x\n",INFO_IND_INFOELEMENT(CMSG)[2]);
1586
 
                                ast_log(LOG_ERROR,"%#x\n",INFO_IND_INFOELEMENT(CMSG)[3]);
1587
 
                            } */
1588
 
#ifndef NEVER_EVER_EARLY_B3_CONNECTS
1589
 
                            if ((INFO_IND_INFONUMBER(CMSG) == 0x001e) && (p->i->doB3 != AST_CAPI_B3_DONT) && (p->i->earlyB3 == -1) && (p->i->state != CAPI_STATE_BCONNECTED)){
1590
 
                                // ETSI 300 102-1 Progress Indicator
1591
 
                                // we do early B3 Connect
1592
 
                                if(INFO_IND_INFOELEMENT(CMSG)[0] >= 2) {
1593
 
                                    if(INFO_IND_INFOELEMENT(CMSG)[2] & 0x2) {
1594
 
                                        p->i->calledPartyIsISDN = 0;
1595
 
                                        // ast_log(LOG_NOTICE,"A N A L O G \n");
1596
 
                                    } else {
1597
 
                                        p->i->calledPartyIsISDN = 1;
1598
 
                                        // ast_log(LOG_NOTICE,"I S D N\n");
1599
 
                                    }
1600
 
                                    if(INFO_IND_INFOELEMENT(CMSG)[2] & 0x88) {
1601
 
                                         // in-band info available
1602
 
                                        p->i->earlyB3 = 1;
1603
 
                                        memset(&CMSG2,0,sizeof(_cmsg));
1604
 
                                        CONNECT_B3_REQ_HEADER(&CMSG2, ast_capi_ApplID, ast_capi_MessageNumber++,0);
1605
 
                                        CONNECT_B3_REQ_PLCI(&CMSG2) = PLCI;
1606
 
                                        if ((error = _capi_put_cmsg(&CMSG2)) != 0) {
1607
 
                                            ast_log(LOG_ERROR,"error sending early CONNECT_B3_REQ (error=%#x)\n",error);
1608
 
                                            return -1;
1609
 
                                        } else {
1610
 
                                            if (option_verbose > 1) {
1611
 
                                                if (capidebug)
1612
 
                                                    ast_verbose(VERBOSE_PREFIX_4 "sent early CONNECT_B3_REQ (PLCI=%#x)\n",PLCI);
1613
 
                                            }
1614
 
                                        }
1615
 
                                    }
1616
 
                                }
1617
 
                            }
1618
 
                            // DISCONNECT
1619
 
                            if ((INFO_IND_INFONUMBER(CMSG) == 0x8045) && (PLCI == p->i->onholdPLCI)) {
1620
 
                                // the caller onhold hung up (or ECTed away)
1621
 
                                // send a disconnect_req , we cannot hangup the channel here!!!
1622
 
                                memset(&CMSG2,0,sizeof(_cmsg));
1623
 
                                DISCONNECT_REQ_HEADER(&CMSG2, ast_capi_ApplID, ast_capi_MessageNumber++, 0);
1624
 
                                DISCONNECT_REQ_PLCI(&CMSG2) = p->i->onholdPLCI;
1625
 
 
1626
 
                                if ((error = _capi_put_cmsg(&CMSG2)) != 0) {
1627
 
                                    ast_log(LOG_NOTICE, "error sending DISCONNECT_REQ PLCI=%#x\n",PLCI);
1628
 
                                } else {
1629
 
                                    if (option_verbose > 1) {
1630
 
                                        if (capidebug)
1631
 
                                            ast_verbose(VERBOSE_PREFIX_4 "sent DISCONNECT_REQ for onholdPLCI=%#x\n",PLCI);
1632
 
                                    }
1633
 
                                }                               
1634
 
                                return 0;
1635
 
                            }
1636
 
 
1637
 
                            // case 1: B3 on success or no B3 at all
1638
 
                            if ((INFO_IND_INFONUMBER(CMSG) == 0x8045) && (p->i->doB3 != AST_CAPI_B3_ALWAYS) && (p->i->outgoing == 1)) {
1639
 
                                p->i->earlyB3 = 0; // !!!
1640
 
                                fr.frametype = AST_FRAME_NULL;
1641
 
                                fr.datalen = 0;
1642
 
                                return pipe_frame(p,(struct ast_frame *)&fr);
1643
 
                            }
1644
 
                            // case 2: we are doing B3, and receive the 0x8045 after a successful call
1645
 
                            if ((INFO_IND_INFONUMBER(CMSG) == 0x8045) && (p->i->doB3 != AST_CAPI_B3_DONT) && (p->i->earlyB3 == 0) && (p->i->outgoing == 1)) {
1646
 
                                fr.frametype = AST_FRAME_NULL;
1647
 
                                fr.datalen = 0;
1648
 
                                return pipe_frame(p,(struct ast_frame *)&fr);
1649
 
                            }
1650
 
                            // case 3: this channel is an incoming channel! the user hung up!
1651
 
                            // it is much better to hangup now instead of waiting for a timeout and
1652
 
                            // network caused DISCONNECT_IND!
1653
 
                            if ((INFO_IND_INFONUMBER(CMSG) == 0x8045) && (p->i->outgoing == 0)) {
1654
 
                            // ast_log(LOG_NOTICE,"case 3\n");
1655
 
                                fr.frametype = AST_FRAME_NULL;
1656
 
                                fr.datalen = 0;
1657
 
                                return pipe_frame(p,(struct ast_frame *)&fr);
1658
 
                            }
1659
 
                            // case 4 (a.k.a. the italian case): B3 always. call is unsuccessful
1660
 
                            if ((INFO_IND_INFONUMBER(CMSG) == 0x8045) && (p->i->doB3 == AST_CAPI_B3_ALWAYS) && (p->i->earlyB3 == -1) && (p->i->outgoing == 1)) {
1661
 
                                // wait for the 0x001e (PROGRESS), play audio and wait for a timeout from the network
1662
 
                                return 0;
1663
 
                            }
1664
 
#endif
1665
 
                            // Handle DID digits
1666
 
                            if ((INFO_IND_INFONUMBER(CMSG) == 0x0070) && p->i->isdnmode && (p->c != NULL)) {
1667
 
                                int search = -1;
1668
 
                                char name[AST_CHANNEL_NAME] = "";
1669
 
                                char *did;
1670
 
 
1671
 
                                did = capi_number(INFO_IND_INFOELEMENT(CMSG),1);
1672
 
                                if (strcasecmp(p->i->dnid, did)) {
1673
 
                                    strncat(p->i->dnid, did, sizeof(p->i->dnid)-1);
1674
 
                                }
1675
 
                                
1676
 
                                snprintf(name,sizeof(name),"CAPI[contr%d/%s]/%d",p->i->controller,p->i->dnid,capi_counter++);
1677
 
                                ast_change_name(p->c, name);
1678
 
                                
1679
 
                                search = search_did(p->c);
1680
 
                                if (search != -1) {
1681
 
                                    if (!search) {
1682
 
                                        ast_setstate(p->c, AST_STATE_RING);
1683
 
                                        // we are alerting (phones ringing)
1684
 
                                        capi_alert(p->c); // Do this here after pbx_start the Channel can be destroyed
1685
 
                                        if (ast_pbx_start(p->c)) {
1686
 
                                            ast_log(LOG_ERROR,"Unable to start pbx on channel!\n");
1687
 
                                            ast_hangup(p->c);
1688
 
                                        } else {
1689
 
                                            if (option_verbose > 2) {
1690
 
                                                if (capidebug)
1691
 
                                                    ast_verbose(VERBOSE_PREFIX_3 "started pbx on channel!\n");
1692
 
                                            }
1693
 
                                        }
1694
 
                                    }
1695
 
                                } else {
1696
 
                                    ast_log(LOG_ERROR,"did not find device for msn = %s\n",p->i->dnid);
1697
 
                                    CONNECT_RESP_HEADER(&CMSG2, ast_capi_ApplID, CMSG->Messagenumber, 0);
1698
 
                                    CONNECT_RESP_PLCI(&CMSG2) = PLCI;
1699
 
                                    CONNECT_RESP_REJECT(&CMSG2) = 1; // ignore
1700
 
                                    if ((error = _capi_put_cmsg(&CMSG2)) != 0) {
1701
 
                                        ast_log(LOG_ERROR,"error sending CONNECT_RESP for PLCI = %#x\n",(int)CONNECT_IND_PLCI(CMSG));
1702
 
                                    } else {
1703
 
                                        if (option_verbose > 5) {
1704
 
                                            if (capidebug)
1705
 
                                                ast_verbose(VERBOSE_PREFIX_4 "sent CONNECT_RESP for PLCI = %#x\n",(int)CONNECT_IND_PLCI(CMSG));
1706
 
                                        }
1707
 
                                    }
1708
 
                                    
1709
 
                                    return 0;
1710
 
                                }
1711
 
                            }
1712
 
                            if (INFO_IND_INFONUMBER(CMSG) == 0x8001) {
1713
 
                                fr.frametype = AST_FRAME_CONTROL;
1714
 
                                fr.subclass = AST_CONTROL_RINGING;
1715
 
                                return pipe_frame(p,(struct ast_frame *)&fr);
1716
 
                            }
1717
 
                            if (INFO_IND_INFONUMBER(CMSG) == 0x800d) {
1718
 
                                fr.frametype = AST_FRAME_CONTROL;
1719
 
                                fr.subclass = AST_CONTROL_PROGRESS;
1720
 
                                return pipe_frame(p,(struct ast_frame *)&fr);
1721
 
                            }
1722
 
                            if (INFO_IND_INFONUMBER(CMSG) == 0x74) {
1723
 
                                strncpy(p->i->owner->exten,capi_number(INFO_IND_INFOELEMENT(CMSG),3),sizeof(p->i->owner->exten)-1);
1724
 
                                strncpy(p->i->owner->dnid,capi_number(INFO_IND_INFOELEMENT(CMSG),3),sizeof(p->i->owner->dnid)-1);
1725
 
                                ast_log(LOG_NOTICE,"%s\n",capi_cmsg2str(CMSG));
1726
 
                            }
1727
 
                            if (INFO_IND_INFONUMBER(CMSG) == 0x28) {
1728
 
                        //      ast_sendtext(p->i->owner,capi_number(INFO_IND_INFOELEMENT(CMSG),0));
1729
 
                        //      struct ast_frame ft = { AST_FRAME_TEXT, capi_number(INFO_IND_INFOELEMENT(CMSG),0), };
1730
 
                        //      ast_queue_frame(p->i->owner, &ft);
1731
 
                        //      ast_log(LOG_NOTICE,"%s\n",capi_number(INFO_IND_INFOELEMENT(CMSG),0));
1732
 
                            }
1733
 
                            break;
1734
 
                        case CAPI_CONNECT_ACTIVE:
1735
 
//                          ast_log(LOG_NOTICE,"CONNECT_ACTIVE_IND PLCI=%#x\n",(int)CONNECT_ACTIVE_IND_PLCI(CMSG));
1736
 
                            CONNECT_ACTIVE_RESP_HEADER(&CMSG2, ast_capi_ApplID, CMSG->Messagenumber,0);
1737
 
                            CONNECT_ACTIVE_RESP_PLCI(&CMSG2) = PLCI;
1738
 
                            if ((error = _capi_put_cmsg(&CMSG2)) != 0) {
1739
 
                                ast_log(LOG_ERROR,"error sending CONNECT_ACTIVE_RESP (error=%#x)\n",error);
1740
 
                                return -1;
1741
 
                            } else {
1742
 
                                if (option_verbose > 5) {
1743
 
                                    if (capidebug)
1744
 
                                        ast_verbose(VERBOSE_PREFIX_4 "sent CONNECT_ACTIVE_RESP (PLCI=%#x)\n",PLCI);
1745
 
                                }
1746
 
                            }
1747
 
                            // normal processing
1748
 
                            if (p->i->earlyB3 != 1) {
1749
 
                                p->i->state = CAPI_STATE_CONNECTED;
1750
 
                            
1751
 
                                // send a CONNECT_B3_REQ
1752
 
                                if (p->i->outgoing == 1) {
1753
 
                                    // outgoing call
1754
 
                                    memset(&CMSG2,0,sizeof(_cmsg));
1755
 
                                    CONNECT_B3_REQ_HEADER(&CMSG2, ast_capi_ApplID, ast_capi_MessageNumber++,0);
1756
 
                                    CONNECT_B3_REQ_PLCI(&CMSG2) = PLCI;
1757
 
                                    if ((error = _capi_put_cmsg(&CMSG2)) != 0) {
1758
 
                                        ast_log(LOG_ERROR,"error sending CONNECT_B3_REQ (error=%#x)\n",error);
1759
 
                                        return -1;
1760
 
                                    } else {
1761
 
                                        if (option_verbose > 1) {
1762
 
                                            if (capidebug)
1763
 
                                                ast_verbose(VERBOSE_PREFIX_3 "sent CONNECT_B3_REQ (PLCI=%#x)\n",PLCI);
1764
 
                                        }
1765
 
                                    }
1766
 
                                } else {
1767
 
                                    // incoming call
1768
 
                                    // RESP already sent ... wait for CONNECT_B3_IND
1769
 
//                                  ast_log(LOG_NOTICE,"waiting for CONNECT_B3_IND\n");
1770
 
                                }
1771
 
                            } else {
1772
 
                                // special treatment for early B3 connects
1773
 
                                p->i->state = CAPI_STATE_BCONNECTED;
1774
 
                                if (p->c->_state != AST_STATE_UP) {
1775
 
                                    ast_setstate(p->c,AST_STATE_UP);
1776
 
                                }
1777
 
                                p->i->earlyB3 = 0;      // not early anymore
1778
 
                                fr.frametype = AST_FRAME_CONTROL;
1779
 
                                fr.subclass = AST_CONTROL_ANSWER;
1780
 
                                fr.datalen = 0;
1781
 
                                return pipe_frame(p,(struct ast_frame *)&fr);
1782
 
                                
1783
 
                            }
1784
 
                            break;
1785
 
                        case CAPI_CONNECT_B3:
1786
 
                            // then send a CONNECT_B3_RESP
1787
 
                            memset(&CMSG2,0,sizeof(_cmsg));
1788
 
                            CONNECT_B3_RESP_HEADER(&CMSG2, ast_capi_ApplID, CMSG->Messagenumber, 0);
1789
 
                            CONNECT_B3_RESP_NCCI(&CMSG2) = CONNECT_B3_IND_NCCI(CMSG);
1790
 
                            p->NCCI = CONNECT_B3_IND_NCCI(CMSG);
1791
 
                            p->i->NCCI = p->NCCI;
1792
 
                            CONNECT_B3_RESP_REJECT(&CMSG2) = 0;
1793
 
 
1794
 
                            if ((error = _capi_put_cmsg(&CMSG2)) != 0) {
1795
 
                                ast_log(LOG_ERROR,"error sending CONNECT_B3_RESP (error=%#x)\n",error);
1796
 
                                return -1;
1797
 
                            } else {
1798
 
                                if (option_verbose > 5) {
1799
 
                                    if (capidebug)
1800
 
                                        ast_verbose(VERBOSE_PREFIX_4 "sent CONNECT_B3_RESP (NCCI=%#x)\n",p->i->NCCI);
1801
 
                                }
1802
 
                            }
1803
 
                /*          if (p->i->controller > 0) {
1804
 
                                capi_controllers[p->i->controller]->nfreebchannels--;
1805
 
                            } */
1806
 
                            break; 
1807
 
                        case CAPI_CONNECT_B3_ACTIVE:
1808
 
//                          ast_log(LOG_NOTICE,"CONNECT_B3_ACTIVE_IND NCCI=%#x\n",p->i->NCCI);
1809
 
                            // then send a CONNECT_B3__ACTIVERESP
1810
 
 
1811
 
                            CONNECT_B3_ACTIVE_RESP_HEADER(&CMSG2, ast_capi_ApplID, CMSG->Messagenumber, 0);
1812
 
                            CONNECT_B3_ACTIVE_RESP_NCCI(&CMSG2) = p->i->NCCI;
1813
 
 
1814
 
                            if ((error = _capi_put_cmsg(&CMSG2)) != 0) {
1815
 
                                ast_log(LOG_ERROR,"error sending CONNECT_B3_ACTIVE_RESP (error=%#x)\n",error);
1816
 
                                return -1;
1817
 
                            } else {
1818
 
                                if (option_verbose > 5) {
1819
 
                                    if (capidebug)
1820
 
                                        ast_verbose(VERBOSE_PREFIX_4 "sent CONNECT_B3_ACTIVE_RESP (NCCI=%#x)\n",p->i->NCCI);
1821
 
                                }
1822
 
                            }
1823
 
 
1824
 
                            ast_mutex_lock(&contrlock);
1825
 
                            if (p->i->controller > 0) {
1826
 
                                capi_controllers[p->i->controller]->nfreebchannels--;
1827
 
                            }
1828
 
                            ast_mutex_unlock(&contrlock);
1829
 
 
1830
 
                            p->i->state = CAPI_STATE_BCONNECTED;
1831
 
                            capi_echo_canceller(p->c,EC_FUNCTION_ENABLE);
1832
 
                            capi_detect_dtmf(p->c,1);
1833
 
 
1834
 
                            if (p->i->earlyB3 != 1) {
1835
 
                                ast_setstate(p->c,AST_STATE_UP);
1836
 
                                fr.frametype = AST_FRAME_CONTROL;
1837
 
                                fr.subclass = AST_CONTROL_ANSWER;
1838
 
                                fr.datalen = 0;
1839
 
                                return pipe_frame(p,(struct ast_frame *)&fr);
1840
 
                            }
1841
 
                            return 0;
1842
 
                            break;
1843
 
                    }
1844
 
                    break;
1845
 
 
1846
 
                case CAPI_CONF:
1847
 
                    switch (CMSG->Command) {
1848
 
                        case CAPI_FACILITY:
1849
 
                            if (FACILITY_CONF_FACILITYSELECTOR(CMSG) == 0x3) {
1850
 
                                if ((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(CMSG)[1] == 0x2) && (FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(CMSG)[2] == 0x0)) {
1851
 
                                    if ((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(CMSG)[4] == 0x0) && (FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(CMSG)[5] == 0x0)) {
1852
 
                                    } else {
1853
 
                                        p->i->state = CAPI_STATE_BCONNECTED;
1854
 
                                        if (capidebug)
1855
 
                                            ast_log(LOG_NOTICE,"%s\n",capi_cmsg2str(CMSG));
1856
 
                                    }
1857
 
                                }
1858
 
                            }
1859
 
                            break;
1860
 
                        case CAPI_DATA_B3:
1861
 
//                          ast_log(LOG_NOTICE,"DATA_B3_CONF (NCCI %#x) for DATAHANDLE %#x\n",DATA_B3_CONF_NCCI(CMSG),DATA_B3_CONF_DATAHANDLE(CMSG));
1862
 
                            break;
1863
 
                        case CAPI_ALERT:
1864
 
//                          ast_log(LOG_NOTICE,"ALERT_CONF (PLCI=%#x)\n",(int)ALERT_CONF_PLCI(CMSG));
1865
 
                            p->i->state = CAPI_STATE_ALERTING;
1866
 
                            if (p->c->_state == AST_STATE_RING) {
1867
 
                                p->c->rings = 1;
1868
 
                            }
1869
 
                            break;
1870
 
                        case CAPI_CONNECT:
1871
 
                            if (option_verbose > 1) {
1872
 
                                if (capidebug)
1873
 
                                    ast_verbose(VERBOSE_PREFIX_2 "received CONNECT_CONF PLCI = %#x INFO = %#x\n",(int)CONNECT_CONF_PLCI(CMSG),CONNECT_CONF_INFO(CMSG));
1874
 
                            }
1875
 
                            if (CONNECT_CONF_INFO(CMSG) == 0) {
1876
 
                                p->i->PLCI = CONNECT_CONF_PLCI(CMSG);
1877
 
                                p->PLCI = p->i->PLCI;
1878
 
                                ast_setstate(p->c,AST_STATE_DIALING);
1879
 
                            } else {
1880
 
        // here, something has to be done -->
1881
 
                                fr.frametype = AST_FRAME_CONTROL;
1882
 
                                fr.subclass = AST_CONTROL_BUSY;
1883
 
                                fr.datalen = 0;
1884
 
                                return pipe_frame(p,(struct ast_frame *)&fr);
1885
 
                            }
1886
 
                            break;
1887
 
                        case CAPI_CONNECT_B3:
1888
 
//                          ast_log(LOG_NOTICE,"received CONNECT_B3_CONF NCCI = %#x INFO = %#x\n",(int)CONNECT_B3_CONF_NCCI(CMSG),CONNECT_B3_CONF_INFO(CMSG));
1889
 
                            if (CONNECT_B3_CONF_INFO(CMSG) == 0) {
1890
 
                                p->i->NCCI = CONNECT_B3_CONF_NCCI(CMSG);
1891
 
                            } else {
1892
 
                                p->i->earlyB3 = -1;
1893
 
                                p->i->doB3 = AST_CAPI_B3_DONT;
1894
 
                            }
1895
 
                            break;
1896
 
                    }
1897
 
                    break;                  
1898
 
            }
1899
 
        }
1900
 
//      ast_log(LOG_NOTICE,"returning\n");
1901
 
        return 0;
1902
 
}
1903
 
 
1904
 
static void capi_handle_msg(_cmsg *CMSG) {
1905
 
    struct ast_capi_pvt *i;
1906
 
    char *DNID;
1907
 
    char *CID;
1908
 
    char *msn;
1909
 
    _cmsg CMSG2;
1910
 
    MESSAGE_EXCHANGE_ERROR  error;
1911
 
    int PLCI=0,NCCI;
1912
 
    int NPLAN=0;
1913
 
    int fds[2];
1914
 
    int controller=0;
1915
 
    char buffer[AST_MAX_EXTENSION];
1916
 
    struct capi_pipe *p;
1917
 
    char *magicmsn = "*\0";
1918
 
    char *emptyid = "\0";
1919
 
    char *emptydnid = "s\0";
1920
 
    long flags;
1921
 
#ifdef DEFLECT_ON_CIRCUITBUSY
1922
 
    int deflect=0;
1923
 
#endif
1924
 
    
1925
 
    switch (CMSG->Subcommand) {
1926
 
        // indication msgs      
1927
 
        case CAPI_IND:
1928
 
 
1929
 
        switch (CMSG->Command) {
1930
 
            case CAPI_CONNECT:  // only connect_ind are global (not channel specific)
1931
 
                if (capidebug)
1932
 
                    ast_log(LOG_NOTICE,"%s\n",capi_cmsg2str(CMSG));
1933
 
                DNID = capi_number(CONNECT_IND_CALLEDPARTYNUMBER(CMSG),1);
1934
 
                if ((DNID && *DNID == 0) || !DNID) {
1935
 
                    DNID = emptydnid;
1936
 
                }
1937
 
                NPLAN = (CONNECT_IND_CALLINGPARTYNUMBER(CMSG)[1] & 0x70);
1938
 
                CID = capi_number(CONNECT_IND_CALLINGPARTYNUMBER(CMSG),2);
1939
 
                PLCI = CONNECT_IND_PLCI(CMSG);
1940
 
                controller = PLCI & 0xff;
1941
 
                if (option_verbose > 1) {
1942
 
                    if (capidebug)
1943
 
                        ast_verbose(VERBOSE_PREFIX_2 "CONNECT_IND (PLCI=%#x,DID=%s,CID=%s,CIP=%#x,CONTROLLER=%#x)\n",PLCI,DNID,CID,CONNECT_IND_CIPVALUE(CMSG),controller);
1944
 
                }
1945
 
                if(CONNECT_IND_BCHANNELINFORMATION(CMSG))
1946
 
                if ((CONNECT_IND_BCHANNELINFORMATION(CMSG)[1] == 0x02) && (!capi_controllers[controller]->isdnmode)) {
1947
 
                    // this is a call waiting CONNECT_IND with BChannelinformation[1] == 0x02
1948
 
                    // meaning "no B or D channel for this call", since we can't do anything with call waiting now
1949
 
                    // just reject it with "user busy"
1950
 
                    // however...if we are a p2p BRI then the telco switch will allow us to choose the b channel
1951
 
                    // so it will look like a callwaiting connect_ind to us
1952
 
 
1953
 
                    ast_log(LOG_ERROR,"received a call waiting CONNECT_IND\n");
1954
 
#ifndef DEFLECT_ON_CIRCUITBUSY
1955
 
                    CONNECT_RESP_HEADER(&CMSG2, ast_capi_ApplID, CMSG->Messagenumber, 0);
1956
 
                    CONNECT_RESP_PLCI(&CMSG2) = CONNECT_IND_PLCI(CMSG);
1957
 
                    CONNECT_RESP_REJECT(&CMSG2) = 3; // user is busy
1958
 
                    if ((error = _capi_put_cmsg(&CMSG2)) != 0) {
1959
 
                       ast_log(LOG_ERROR,"error sending CONNECT_RESP for PLCI = %#x\n",(int)CONNECT_IND_PLCI(CMSG));
1960
 
                    } else {
1961
 
                       if (option_verbose > 5) {
1962
 
                            if (capidebug)
1963
 
                                ast_verbose(VERBOSE_PREFIX_4 "sent CONNECT_RESP for PLCI = %#x\n",(int)CONNECT_IND_PLCI(CMSG));
1964
 
                       }
1965
 
                    }
1966
 
                    // no need to pipe this
1967
 
                    PLCI = 0;
1968
 
                    break;              
1969
 
#else
1970
 
                    deflect = 1;
1971
 
#endif
1972
 
                }
1973
 
                // well...somebody is calling us. let's set up a channel
1974
 
                ast_mutex_lock(&iflock);
1975
 
                i = iflist;
1976
 
                while(i) {
1977
 
                    //XXX test this!
1978
 
                    // has no owner
1979
 
                    if ((!i->owner) && (i->incomingmsn != NULL)){
1980
 
                        strncpy(buffer,i->incomingmsn,sizeof(buffer)-1);
1981
 
                        msn = strtok(buffer,",");
1982
 
                        while (msn != NULL) {
1983
 
//                      ast_log(LOG_NOTICE,"msn=%s\n",msn);
1984
 
                            if (DNID && ((!strcasecmp(msn,DNID)) ||
1985
 
                                 (i->isdnmode && (strlen(msn)<strlen(DNID)) && !strncasecmp(msn, DNID, strlen(msn))) || (!strncasecmp(msn,magicmsn,strlen(msn)))) && 
1986
 
                                (i->controllers & (1 << controller))) {
1987
 
                                if (CID != NULL) {
1988
 
                                    if(NPLAN == CAPI_ETSI_NPLAN_NATIONAL)
1989
 
                                        snprintf(i->cid, (sizeof(i->cid)-1), "%s%s%s", i->prefix, capi_national_prefix, CID);
1990
 
                                    else if(NPLAN == CAPI_ETSI_NPLAN_INTERNAT)
1991
 
                                        snprintf(i->cid, (sizeof(i->cid)-1), "%s%s%s", i->prefix, capi_international_prefix, CID);
1992
 
                                    else
1993
 
                                        snprintf(i->cid, (sizeof(i->cid)-1), "%s%s", i->prefix, CID);
1994
 
                                } else
1995
 
                                    strncpy(i->cid,emptyid,sizeof(i->cid)-1);
1996
 
 
1997
 
                                if (DNID != NULL) 
1998
 
                                    strncpy(i->dnid,DNID,sizeof(i->dnid)-1);
1999
 
                                else
2000
 
                                    strncpy(i->dnid,emptydnid,sizeof(i->dnid)-1);
2001
 
                                
2002
 
                                i->controller=controller;
2003
 
                                i->PLCI = PLCI;
2004
 
                                i->MessageNumber = CMSG->Messagenumber;
2005
 
                                if (pipe(fds) == 0) {
2006
 
                                    if (option_verbose > 4) {
2007
 
                                        ast_verbose(VERBOSE_PREFIX_3 "creating pipe for PLCI=%#x msn = %s\n",PLCI,msn);
2008
 
                                    }
2009
 
                                    i->fd = fds[0];
2010
 
                                    flags = fcntl(i->fd,F_GETFL);
2011
 
                                    fcntl(i->fd,F_SETFL,flags | O_SYNC | O_DIRECT);
2012
 
//                                  ast_log(LOG_NOTICE,"i->fd = %d\n",i->fd);
2013
 
                                    p = malloc(sizeof(struct capi_pipe));
2014
 
                                    memset(p, 0, sizeof(struct capi_pipe));
2015
 
                                    p->fd = fds[1];
2016
 
                                    flags = fcntl(i->fd,F_GETFL);
2017
 
                                    fcntl(p->fd,F_SETFL,flags | O_SYNC | O_DIRECT);
2018
 
//                                  ast_log(LOG_NOTICE,"p->fd = %d\n",p->fd);
2019
 
                                    p->PLCI = PLCI;
2020
 
                                    p->i = i;
2021
 
                                    ast_pthread_mutex_init(&(p->lock),NULL);
2022
 
                                    i->mypipe = p;
2023
 
                                    if (i->isdnmode) {
2024
 
                                        p->c = capi_new(i,AST_STATE_DOWN);
2025
 
                                        i->state = CAPI_STATE_DID;
2026
 
                                    } else {
2027
 
                                        p->c = capi_new(i,AST_STATE_RING);
2028
 
                                    }
2029
 
                                    p->next = pipelist;
2030
 
                                    pipelist = p;
2031
 
                                // hmmm....
2032
 
                                    ast_mutex_unlock(&iflock);
2033
 
#ifdef DEFLECT_ON_CIRCUITBUSY
2034
 
                                    if ((deflect == 1) && (i->deflect2)) {
2035
 
                                        capi_deflect(p->c,i->deflect2);
2036
 
                                    }
2037
 
#endif
2038
 
                                    return;
2039
 
                                } else {
2040
 
                                    ast_log(LOG_ERROR,"creating pipe for PLCI=%#x failed\n",PLCI);
2041
 
                                }
2042
 
                                break;
2043
 
                            } // if strcasecmp
2044
 
                            msn = strtok(NULL,",");
2045
 
                        } // while strtok
2046
 
                    } // if
2047
 
                    i = i->next;
2048
 
                } // while interface list
2049
 
                ast_mutex_unlock(&iflock);              // obviously we are not called...so tell capi to ignore this call
2050
 
                if (capidebug) {
2051
 
                    ast_log(LOG_ERROR,"did not find device for msn = %s\n",DNID);
2052
 
                }
2053
 
                CONNECT_RESP_HEADER(&CMSG2, ast_capi_ApplID, CMSG->Messagenumber, 0);
2054
 
                CONNECT_RESP_PLCI(&CMSG2) = CONNECT_IND_PLCI(CMSG);
2055
 
                CONNECT_RESP_REJECT(&CMSG2) = 1; // ignore
2056
 
                if ((error = _capi_put_cmsg(&CMSG2)) != 0) {
2057
 
                    ast_log(LOG_ERROR,"error sending CONNECT_RESP for PLCI = %#x\n",(int)CONNECT_IND_PLCI(CMSG));
2058
 
                } else {
2059
 
                    if (option_verbose > 5) {
2060
 
                        if (capidebug)
2061
 
                            ast_verbose(VERBOSE_PREFIX_4 "sent CONNECT_RESP for PLCI = %#x\n",(int)CONNECT_IND_PLCI(CMSG));
2062
 
                    }
2063
 
                }
2064
 
                ast_mutex_lock(&pipelock);
2065
 
                if (pipelist == NULL) {
2066
 
                    capi_last_plci = PLCI;
2067
 
                }
2068
 
                ast_mutex_unlock(&pipelock);
2069
 
                // no need to pipe this
2070
 
                PLCI = 0;
2071
 
//              ast_mutex_unlock(&iflock);
2072
 
//              return;
2073
 
                break;
2074
 
            case CAPI_FACILITY:
2075
 
                PLCI = FACILITY_IND_PLCI(CMSG) & 0xffff;  // this is for you eicon
2076
 
                if (option_verbose > 3) {
2077
 
                    if (capidebug)
2078
 
                        ast_verbose(VERBOSE_PREFIX_3 "%s\n",capi_cmsg2str(CMSG));
2079
 
                }
2080
 
//              ast_log(LOG_ERROR,"FACILITY_IND PLCI=%#x\n",PLCI);
2081
 
            break;
2082
 
            case CAPI_INFO:
2083
 
                PLCI = INFO_IND_PLCI(CMSG);
2084
 
                if (option_verbose > 3) {
2085
 
                    if (capidebug)
2086
 
                        ast_verbose(VERBOSE_PREFIX_3 "%s\n",capi_cmsg2str(CMSG));
2087
 
                }
2088
 
//              ast_log(LOG_ERROR,"INFO_IND PLCI=%#x INFO# = %#x\n",PLCI,INFO_IND_INFONUMBER(CMSG));
2089
 
            break;
2090
 
            case CAPI_CONNECT_ACTIVE:
2091
 
                PLCI = CONNECT_ACTIVE_IND_PLCI(CMSG);
2092
 
                if (option_verbose > 3) {
2093
 
                    if (capidebug)
2094
 
                        ast_verbose(VERBOSE_PREFIX_3 "%s\n",capi_cmsg2str(CMSG));
2095
 
                }
2096
 
//              ast_log(LOG_ERROR,"CONNECT_ACTIVE_IND PLCI=%#x\n",PLCI);
2097
 
            break;
2098
 
            case CAPI_CONNECT_B3:
2099
 
                NCCI = CONNECT_B3_IND_NCCI(CMSG);
2100
 
                PLCI = (NCCI << 16) >> 16;
2101
 
                if (option_verbose > 3) {
2102
 
                    if (capidebug)
2103
 
                        ast_verbose(VERBOSE_PREFIX_3 "%s\n",capi_cmsg2str(CMSG));
2104
 
                }
2105
 
//              ast_log(LOG_ERROR,"CONNECT_B3_IND NCCI=%#x PLCI=%#x\n",NCCI,PLCI);
2106
 
            break;
2107
 
            case CAPI_CONNECT_B3_ACTIVE:
2108
 
                NCCI = CONNECT_B3_IND_NCCI(CMSG);
2109
 
                PLCI = (NCCI << 16) >> 16;
2110
 
                if (option_verbose > 3) {
2111
 
                    if (capidebug)
2112
 
                        ast_verbose(VERBOSE_PREFIX_3 "%s\n",capi_cmsg2str(CMSG));
2113
 
                }
2114
 
//              ast_log(LOG_ERROR,"CONNECT_B3_ACTIVE_IND NCCI=%#x PLCI=%#x\n",NCCI,PLCI);
2115
 
            break;
2116
 
            case CAPI_DATA_B3:
2117
 
                NCCI = DATA_B3_IND_NCCI(CMSG);
2118
 
                PLCI = (NCCI << 16) >> 16;
2119
 
//              ast_log(LOG_ERROR,"DATA_B3_IND NCCI=%#x PLCI=%#x\n",NCCI,PLCI);
2120
 
            break;
2121
 
            case CAPI_DISCONNECT_B3:
2122
 
                NCCI = DISCONNECT_B3_IND_NCCI(CMSG);
2123
 
                PLCI = (NCCI << 16) >> 16;
2124
 
                if (option_verbose > 1) {
2125
 
                    if (capidebug)
2126
 
                        ast_verbose(VERBOSE_PREFIX_2 "DISCONNECT_B3_IND NCCI=%#x\n",NCCI);
2127
 
                }
2128
 
            break;
2129
 
            case CAPI_DISCONNECT:
2130
 
                PLCI = DISCONNECT_IND_PLCI(CMSG);
2131
 
                if (option_verbose > 1) {
2132
 
                    if (capidebug)
2133
 
                        ast_verbose(VERBOSE_PREFIX_2 "DISCONNECT_IND PLCI=%#x REASON=%#x\n",PLCI,DISCONNECT_IND_REASON(CMSG));
2134
 
                }
2135
 
            break;
2136
 
            default:
2137
 
                ast_log(LOG_ERROR,"Command.Subcommand = %#x.%#x\n",CMSG->Command,CMSG->Subcommand);
2138
 
        }
2139
 
        break;
2140
 
        // confirmation msgs
2141
 
        case CAPI_CONF:
2142
 
        switch (CMSG->Command) {
2143
 
            case CAPI_FACILITY:
2144
 
                NCCI = FACILITY_CONF_NCCI(CMSG);
2145
 
                PLCI = (NCCI << 16) >> 16;
2146
 
                if (option_verbose > 2) {
2147
 
                        if (FACILITY_CONF_FACILITYSELECTOR(CMSG) == 6) {
2148
 
                                if (FACILITY_CONF_INFO(CMSG)) 
2149
 
                                        ast_verbose (VERBOSE_PREFIX_3 "Error setting up echo canceller (PLCI=%#x, Info=%#04x)\n", PLCI, FACILITY_CONF_INFO(CMSG));
2150
 
                                else
2151
 
                                        ast_verbose (VERBOSE_PREFIX_3 "Echo canceller successfully set up (PLCI=%#x)\n",PLCI);
2152
 
                        }
2153
 
                }
2154
 
                if (option_verbose > 3) {
2155
 
                    if (capidebug)
2156
 
                        ast_verbose(VERBOSE_PREFIX_3 "%s\n",capi_cmsg2str(CMSG));
2157
 
                }
2158
 
//              ast_log(LOG_ERROR,"FACILITY_CONF NCCI=%#x INFO=%#x\n",(int)FACILITY_CONF_NCCI(CMSG),FACILITY_CONF_INFO(CMSG));
2159
 
            break;
2160
 
            case CAPI_INFO:
2161
 
                PLCI = INFO_CONF_PLCI(CMSG);
2162
 
//              ast_log(LOG_ERROR,"INFO_CONF PLCI=%#x INFO=%#x\n",PLCI,INFO_CONF_INFO(CMSG));
2163
 
            break;
2164
 
            case CAPI_CONNECT:
2165
 
                PLCI = CONNECT_CONF_PLCI(CMSG);
2166
 
                if (option_verbose > 3) {
2167
 
                    if (capidebug)
2168
 
                        ast_verbose(VERBOSE_PREFIX_3 "%s\n",capi_cmsg2str(CMSG));
2169
 
                }
2170
 
//              ast_log(LOG_ERROR,"CONNECT_CONF PLCI=%#x INFO=%#x MN=%#x\n",PLCI,CONNECT_CONF_INFO(CMSG),CMSG->Messagenumber);
2171
 
            break;
2172
 
            case CAPI_DISCONNECT:
2173
 
                PLCI = DISCONNECT_CONF_PLCI(CMSG);
2174
 
                if (option_verbose > 3) {
2175
 
                    if (capidebug)
2176
 
                        ast_verbose(VERBOSE_PREFIX_3 "%s\n",capi_cmsg2str(CMSG));
2177
 
                }
2178
 
//              ast_log(LOG_ERROR,"DISCONNECT_CONF PLCI=%#x INFO=%#x MN=%#x\n",PLCI,DISCONNECT_CONF_INFO(CMSG),CMSG->Messagenumber);
2179
 
            break;
2180
 
            case CAPI_DISCONNECT_B3:
2181
 
                NCCI = DISCONNECT_B3_CONF_NCCI(CMSG);
2182
 
                PLCI = (NCCI << 16) >> 16;
2183
 
                if (option_verbose > 3) {
2184
 
                    if (capidebug)
2185
 
                        ast_verbose(VERBOSE_PREFIX_3 "%s\n",capi_cmsg2str(CMSG));
2186
 
                }
2187
 
//              ast_log(LOG_ERROR,"DISCONNECT_B3_CONF NCCI=%#x INFO=%#x MN=%#x\n",NCCI,DISCONNECT_B3_CONF_INFO(CMSG),CMSG->Messagenumber);
2188
 
            break;
2189
 
            case CAPI_CONNECT_B3:
2190
 
                NCCI = CONNECT_B3_CONF_NCCI(CMSG);
2191
 
                PLCI = (NCCI << 16) >> 16;
2192
 
                if (option_verbose > 3) {
2193
 
                    if (capidebug)
2194
 
                        ast_verbose(VERBOSE_PREFIX_3 "%s\n",capi_cmsg2str(CMSG));
2195
 
                }
2196
 
//                  ast_log(LOG_ERROR,"CONNECT_B3_CONF PLCI=%#x INFO=%#x MN=%#x\n",PLCI,CONNECT_B3_CONF_INFO(CMSG),CMSG->Messagenumber);
2197
 
            break;
2198
 
            case CAPI_ALERT:
2199
 
                PLCI = ALERT_CONF_PLCI(CMSG);
2200
 
                if (option_verbose > 3) {
2201
 
                    if (capidebug)
2202
 
                        ast_verbose(VERBOSE_PREFIX_3 "%s\n",capi_cmsg2str(CMSG));
2203
 
                }
2204
 
//              ast_log(LOG_ERROR,"ALERT_CONF PLCI=%#x\n",PLCI);
2205
 
            break;          
2206
 
            case CAPI_DATA_B3:
2207
 
                NCCI = DATA_B3_CONF_NCCI(CMSG);
2208
 
                PLCI = (NCCI << 16) >> 16;
2209
 
                if (option_verbose > 5) {
2210
 
                    if (capidebug)
2211
 
                        ast_verbose(VERBOSE_PREFIX_3 "%s\n",capi_cmsg2str(CMSG));
2212
 
                }
2213
 
//              ast_log(LOG_ERROR,"DATA_B3_CONF NCCI=%#x PLCI=%#x\n",NCCI,PLCI);
2214
 
            break;
2215
 
            default:
2216
 
                ast_log(LOG_ERROR,"Command.Subcommand = %#x.%#x\n",CMSG->Command,CMSG->Subcommand);
2217
 
        }
2218
 
        break;
2219
 
    }
2220
 
    if (PLCI > 0) {
2221
 
        pipe_msg(PLCI,CMSG);
2222
 
    }
2223
 
 
2224
 
}
2225
 
 
2226
 
 
2227
 
 
2228
 
 
2229
 
 
2230
 
// module stuff, monitor...
2231
 
 
2232
 
static void *do_monitor(void *data) {
2233
 
   unsigned int Info;
2234
 
    _cmsg *monCMSG;
2235
 
    for (;;) {
2236
 
/*
2237
 
        if (ast_mutex_lock(&monlock)) {
2238
 
            ast_log(LOG_ERROR,"Unable to get monitor lock!\n");
2239
 
            return NULL;
2240
 
        }
2241
 
        // do some nifty stuff
2242
 
        ast_mutex_unlock(&monlock);
2243
 
*/
2244
 
        monCMSG = malloc(sizeof(_cmsg));
2245
 
        memset(monCMSG,0,sizeof(_cmsg));
2246
 
        switch(Info = check_wait_get_cmsg(monCMSG)) {
2247
 
            case 0x0000:
2248
 
                    if (capidebug)
2249
 
                        ast_verbose(VERBOSE_PREFIX_3 "%s\n",capi_cmsg2str(monCMSG));
2250
 
                capi_handle_msg(monCMSG);
2251
 
                break;
2252
 
            case 0x1104:
2253
 
                // CAPI queue is empty
2254
 
                break;
2255
 
            default:
2256
 
                // something is wrong!
2257
 
                 break;
2258
 
        } //switch
2259
 
        free(monCMSG);
2260
 
    } // for
2261
 
    // never reached
2262
 
    return NULL;
2263
 
}
2264
 
 
2265
 
static int restart_monitor() {
2266
 
    // stay stopped if wanted
2267
 
    if (ast_mutex_lock(&monlock)) {
2268
 
        ast_log(LOG_WARNING,"Unable to get monitor lock!\n");
2269
 
        return -1;
2270
 
    }
2271
 
    if (monitor_thread == pthread_self()) {
2272
 
        ast_mutex_unlock(&monlock);
2273
 
        ast_log(LOG_WARNING,"Unable to kill myself!\n");
2274
 
        return -1;
2275
 
    }
2276
 
    
2277
 
    // restart
2278
 
    if (ast_pthread_create(&monitor_thread,NULL,do_monitor,NULL) < 0) {
2279
 
        ast_mutex_unlock(&monlock);
2280
 
        ast_log(LOG_ERROR,"Unable to start monitor thread!\n");
2281
 
        return -1;
2282
 
    }
2283
 
 
2284
 
    return 0;
2285
 
}
2286
 
 
2287
 
#ifdef CAPI_GAIN
2288
 
static void capi_gains(struct ast_capi_gains *g,float rxgain,float txgain) {
2289
 
    int i=0;
2290
 
    int x=0;
2291
 
    if (rxgain != 1.0) {
2292
 
        for (i=0;i<256;i++) {
2293
 
            x = (int)(((float)capiXLAW2INT(i)) * rxgain);
2294
 
            if (x > 32767) x = 32767;
2295
 
            if (x < -32767) x = -32767;
2296
 
            g->rxgains[i] = capiINT2XLAW(x);
2297
 
        }
2298
 
    } else {
2299
 
        for (i=0;i<256;i++) {
2300
 
            g->rxgains[i] = i;
2301
 
        }
2302
 
    }
2303
 
    if (txgain != 1.0) {
2304
 
        for (i=0;i<256;i++) {
2305
 
            x = (int)(((float)capiXLAW2INT(i)) * txgain);
2306
 
            if (x > 32767) x = 32767;
2307
 
            if (x < -32767) x = -32767;
2308
 
            g->txgains[i] = capiINT2XLAW(x);
2309
 
        }
2310
 
    } else {
2311
 
        for (i=0;i<256;i++) {
2312
 
            g->txgains[i] = i;
2313
 
        }
2314
 
    }
2315
 
    
2316
 
}
2317
 
#endif
2318
 
#ifdef DEFLECT_ON_CIRCUITBUSY
2319
 
int mkif(char *msn,char *incomingmsn,char *context,char *controllerstr,int devices,int softdtmf,int echocancel,int ecoption,int ectail, char *prefix, int isdnmode, int es,float rxgain,float txgain, char *deflect2, char *accountcode, unsigned int callgroup) {
2320
 
#else
2321
 
int mkif(char *msn,char *incomingmsn,char *context,char *controllerstr,int devices,int softdtmf,int echocancel,int ecoption,int ectail, char *prefix, int isdnmode, int es,float rxgain,float txgain, char *accountcode, unsigned int callgroup) {
2322
 
#endif
2323
 
    struct ast_capi_pvt *tmp;
2324
 
    int i=0;
2325
 
    char buffer[100];
2326
 
    char *contr;
2327
 
    unsigned long contrmap=0;
2328
 
 
2329
 
    for (i=0;i<devices;i++) {
2330
 
        tmp = malloc(sizeof(struct ast_capi_pvt));
2331
 
        memset(tmp, 0, sizeof(struct ast_capi_pvt));
2332
 
        if (tmp) {
2333
 
            ast_pthread_mutex_init(&(tmp->lock),NULL);
2334
 
            strncpy(tmp->context, context, sizeof(tmp->context)-1);
2335
 
            strncpy(tmp->msn, msn, sizeof(tmp->msn)-1);
2336
 
            strncpy(tmp->incomingmsn, incomingmsn, sizeof(tmp->incomingmsn)-1);
2337
 
            strncpy(tmp->prefix, prefix, sizeof(tmp->prefix)-1);
2338
 
            strncpy(tmp->accountcode, accountcode, sizeof(tmp->accountcode)-1);
2339
 
            
2340
 
            strncpy(buffer,controllerstr,sizeof(buffer)-1);
2341
 
            contr = strtok(buffer,",");
2342
 
            while (contr != NULL) {
2343
 
                contrmap |= (1 << atoi(contr));
2344
 
                if (capi_controllers[atoi(contr)]) {
2345
 
                    capi_controllers[atoi(contr)]->isdnmode = isdnmode;
2346
 
                //    ast_log(LOG_NOTICE, "contr %d isdnmode %d\n",atoi(contr),isdnmode);
2347
 
                }
2348
 
                contr = strtok(NULL,",");
2349
 
            }
2350
 
            tmp->controllers = contrmap;
2351
 
            capi_used_controllers |= contrmap;
2352
 
            tmp->controller = 0;
2353
 
            tmp->CLIR = 0;
2354
 
            tmp->earlyB3 = -1;
2355
 
            tmp->onholdPLCI = 0;
2356
 
            tmp->doEC = echocancel;
2357
 
            tmp->ecOption = ecoption;
2358
 
            tmp->ecTail = ectail;
2359
 
            tmp->isdnmode = isdnmode;
2360
 
            tmp->doES = es;
2361
 
            tmp->callgroup = callgroup;
2362
 
#ifdef CAPI_ES      
2363
 
#endif
2364
 
#ifdef CAPI_GAIN
2365
 
            tmp->rxgain = rxgain;
2366
 
            tmp->txgain = txgain;
2367
 
            capi_gains(&tmp->g,rxgain,txgain);
2368
 
#endif
2369
 
#ifdef DEFLECT_ON_CIRCUITBUSY
2370
 
            strncpy(tmp->deflect2, deflect2, sizeof(tmp->deflect2)-1);
2371
 
#endif
2372
 
#ifndef FORCE_SOFTWARE_DTMF
2373
 
            if (softdtmf == 1) {
2374
 
#endif
2375
 
                tmp->doDTMF = 1;
2376
 
#ifndef FORCE_SOFTWARE_DTMF
2377
 
            } else {
2378
 
                tmp->doDTMF = 0;
2379
 
            }
2380
 
#endif
2381
 
            tmp->next = iflist; // prepend
2382
 
            iflist = tmp;
2383
 
        //          ast_log(LOG_NOTICE, "ast_capi_pvt(%s,%s,%s,%#x,%d) (%d,%d,%d) (%d)(%f/%f) %d\n",tmp->msn,tmp->incomingmsn,tmp->context,(int)tmp->controllers,devices,tmp->doEC,tmp->ecOption,tmp->ecTail,tmp->doES,tmp->rxgain,tmp->txgain,callgroup);
2384
 
            if (option_verbose > 2) {
2385
 
                    ast_verbose(VERBOSE_PREFIX_2 "ast_capi_pvt(%s,%s,%s,%d,%d) (%d,%d,%d)\n",tmp->msn,tmp->incomingmsn,tmp->context,tmp->controller,devices,tmp->doEC,tmp->ecOption,tmp->ecTail);
2386
 
            }
2387
 
            
2388
 
        } else {
2389
 
            return -1;
2390
 
        }
2391
 
    }
2392
 
    return 0;
2393
 
}
2394
 
 
2395
 
void supported_sservices(struct ast_capi_controller *cp) {
2396
 
    MESSAGE_EXCHANGE_ERROR error;
2397
 
    _cmsg       CMSG,CMSG2;
2398
 
    struct timeval tv;
2399
 
    char fac[20];
2400
 
 
2401
 
    FACILITY_REQ_HEADER(&CMSG, ast_capi_ApplID, ast_capi_MessageNumber++, 0);
2402
 
    FACILITY_REQ_CONTROLLER(&CMSG) = cp->controller;
2403
 
    FACILITY_REQ_FACILITYSELECTOR(&CMSG) = 0x0003; // sservices
2404
 
    fac[0] = 3;
2405
 
    fac[1] = 0;
2406
 
    fac[2] = 0;
2407
 
    fac[3] = 0;
2408
 
    FACILITY_REQ_FACILITYREQUESTPARAMETER(&CMSG) = (char *)&fac;
2409
 
    if ((error= _capi_put_cmsg(&CMSG)) != 0) {
2410
 
        ast_log(LOG_ERROR,"error sending FACILITY_REQ (error=%#x)\n",error);
2411
 
    } else {
2412
 
        if (option_verbose > 5) {
2413
 
            ast_verbose(VERBOSE_PREFIX_4 "sent FACILITY_REQ (CONTROLLER=%#x)\n",cp->controller);
2414
 
        }
2415
 
    }
2416
 
 
2417
 
    tv.tv_sec = 1;
2418
 
    tv.tv_usec = 0;
2419
 
    for (;;){
2420
 
        error = capi20_waitformessage(ast_capi_ApplID,&tv);
2421
 
        error = capi_get_cmsg(&CMSG2,ast_capi_ApplID); 
2422
 
//        error = check_wait_get_cmsg(&CMSG2);
2423
 
        if (error == 0) {
2424
 
                if (IS_FACILITY_CONF(&CMSG2)) {
2425
 
                    if (option_verbose > 5) {
2426
 
                        ast_verbose(VERBOSE_PREFIX_4 "FACILITY_CONF INFO = %#x\n",FACILITY_CONF_INFO(&CMSG2));
2427
 
                    }
2428
 
                    break;
2429
 
                }
2430
 
        }
2431
 
    } 
2432
 
    // parse supported sservices
2433
 
    if (FACILITY_CONF_FACILITYSELECTOR(&CMSG2) == 0x0003) {
2434
 
        // success
2435
 
        if (FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[4] == 0) {
2436
 
            if ((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[6] & 1) == 1) {
 
3225
        int rtpoffset = 0;
 
3226
 
 
3227
        if (i != NULL) {
 
3228
                if ((i->isdnstate & CAPI_ISDN_STATE_RTP)) rtpoffset = RTP_HEADER_SIZE;
 
3229
                b3len = DATA_B3_IND_DATALENGTH(CMSG);
 
3230
                b3buf = &(i->rec_buffer[AST_FRIENDLY_OFFSET - rtpoffset]);
 
3231
                memcpy(b3buf, (char *)DATA_B3_IND_DATA(CMSG), b3len);
 
3232
        }
 
3233
        
 
3234
        /* send a DATA_B3_RESP very quickly to free the buffer in capi */
 
3235
        DATA_B3_RESP_HEADER(&CMSG2, capi_ApplID, HEADER_MSGNUM(CMSG), 0);
 
3236
        DATA_B3_RESP_NCCI(&CMSG2) = NCCI;
 
3237
        DATA_B3_RESP_DATAHANDLE(&CMSG2) = DATA_B3_IND_DATAHANDLE(CMSG);
 
3238
        _capi_put_cmsg(&CMSG2);
 
3239
 
 
3240
        return_on_no_interface("DATA_B3_IND");
 
3241
 
 
3242
        if (i->fFax) {
 
3243
                /* we are in fax mode and have a file open */
 
3244
                cc_verbose(6, 1, VERBOSE_PREFIX_3 "%s: DATA_B3_IND (len=%d) Fax\n",
 
3245
                        i->vname, b3len);
 
3246
                if (!(i->FaxState & CAPI_FAX_STATE_SENDMODE)) {
 
3247
                        if (fwrite(b3buf, 1, b3len, i->fFax) != b3len)
 
3248
                                cc_log(LOG_WARNING, "%s : error writing output file (%s)\n",
 
3249
                                        i->vname, strerror(errno));
 
3250
                }
 
3251
                return;
 
3252
        }
 
3253
 
 
3254
        if (((i->isdnstate &
 
3255
            (CAPI_ISDN_STATE_B3_CHANGE | CAPI_ISDN_STATE_LI | CAPI_ISDN_STATE_HANGUP))) ||
 
3256
            (i->state == CAPI_STATE_DISCONNECTING)) {
 
3257
                /* drop voice frames when we don't want them */
 
3258
                return;
 
3259
        }
 
3260
 
 
3261
        if ((i->isdnstate & CAPI_ISDN_STATE_RTP)) {
 
3262
                struct ast_frame *f = capi_read_rtp(i, b3buf, b3len);
 
3263
                if (f)
 
3264
                        local_queue_frame(i, f);
 
3265
                return;
 
3266
        }
 
3267
 
 
3268
        if (i->B3q < (((CAPI_MAX_B3_BLOCKS - 1) * CAPI_MAX_B3_BLOCK_SIZE) + 1)) {
 
3269
                i->B3q += b3len;
 
3270
        }
 
3271
 
 
3272
        if ((i->doES == 1)) {
 
3273
                for (j = 0; j < b3len; j++) {
 
3274
                        *(b3buf + j) = reversebits[*(b3buf + j)]; 
 
3275
                        if (capi_capability == AST_FORMAT_ULAW) {
 
3276
                                rxavg += abs(capiULAW2INT[ reversebits[*(b3buf + j)]]);
 
3277
                        } else {
 
3278
                                rxavg += abs(capiALAW2INT[ reversebits[*(b3buf + j)]]);
 
3279
                        }
 
3280
                }
 
3281
                rxavg = rxavg / j;
 
3282
                for (j = 0; j < ECHO_EFFECTIVE_TX_COUNT; j++) {
 
3283
                        txavg += i->txavg[j];
 
3284
                }
 
3285
                txavg = txavg / j;
 
3286
                            
 
3287
                if ( (txavg / ECHO_TXRX_RATIO) > rxavg) {
 
3288
                        if (capi_capability == AST_FORMAT_ULAW) {
 
3289
                                memset(b3buf, 255, b3len);
 
3290
                        } else {
 
3291
                                memset(b3buf, 85, b3len);
 
3292
                        }
 
3293
                        cc_verbose(6, 1, VERBOSE_PREFIX_3 "%s: SUPPRESSING ECHO rx=%d, tx=%d\n",
 
3294
                                        i->vname, rxavg, txavg);
 
3295
                }
 
3296
        } else {
 
3297
                if (i->rxgain == 1.0) {
 
3298
                        for (j = 0; j < b3len; j++) {
 
3299
                                *(b3buf + j) = reversebits[*(b3buf + j)];
 
3300
                        }
 
3301
                } else {
 
3302
                        for (j = 0; j < b3len; j++) {
 
3303
                                *(b3buf + j) = reversebits[i->g.rxgains[*(b3buf + j)]];
 
3304
                        }
 
3305
                }
 
3306
        }
 
3307
 
 
3308
        fr.frametype = AST_FRAME_VOICE;
 
3309
        fr.subclass = capi_capability;
 
3310
        fr.data = b3buf;
 
3311
        fr.datalen = b3len;
 
3312
        fr.samples = b3len;
 
3313
        fr.offset = AST_FRIENDLY_OFFSET;
 
3314
        fr.mallocd = 0;
 
3315
        fr.delivery = ast_tv(0,0);
 
3316
        fr.src = NULL;
 
3317
        cc_verbose(8, 1, VERBOSE_PREFIX_3 "%s: DATA_B3_IND (len=%d) fr.datalen=%d fr.subclass=%d\n",
 
3318
                i->vname, b3len, fr.datalen, fr.subclass);
 
3319
        local_queue_frame(i, &fr);
 
3320
        return;
 
3321
}
 
3322
 
 
3323
/*
 
3324
 * signal 'answer' to PBX
 
3325
 */
 
3326
static void capi_signal_answer(struct capi_pvt *i)
 
3327
{
 
3328
        struct ast_frame fr = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER, };
 
3329
 
 
3330
        if (i->outgoing == 1) {
 
3331
                local_queue_frame(i, &fr);
 
3332
        }
 
3333
}
 
3334
 
 
3335
/*
 
3336
 * send the next data
 
3337
 */
 
3338
static void capidev_send_faxdata(struct capi_pvt *i)
 
3339
{
 
3340
        unsigned char faxdata[CAPI_MAX_B3_BLOCK_SIZE];
 
3341
        size_t len;
 
3342
        _cmsg CMSG;
 
3343
 
 
3344
        if ((i->fFax) && (!(feof(i->fFax)))) {
 
3345
                len = fread(faxdata, 1, CAPI_MAX_B3_BLOCK_SIZE, i->fFax);
 
3346
                if (len > 0) {
 
3347
                        DATA_B3_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(), 0);
 
3348
                        DATA_B3_REQ_NCCI(&CMSG) = i->NCCI;
 
3349
                        DATA_B3_REQ_DATALENGTH(&CMSG) = len;
 
3350
                        DATA_B3_REQ_FLAGS(&CMSG) = 0; 
 
3351
                        DATA_B3_REQ_DATAHANDLE(&CMSG) = i->send_buffer_handle;
 
3352
                        DATA_B3_REQ_DATA(&CMSG) = faxdata;
 
3353
                        i->send_buffer_handle++;
 
3354
                        cc_verbose(5, 1, VERBOSE_PREFIX_3 "%s: send %d fax bytes.\n",
 
3355
                                i->vname, len);
 
3356
                        _capi_put_cmsg(&CMSG);
 
3357
                        return;
 
3358
                }
 
3359
        }
 
3360
        /* finished send fax, so we hangup */
 
3361
        cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: completed faxsend.\n",
 
3362
                i->vname);
 
3363
        DISCONNECT_B3_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(), 0);
 
3364
        DISCONNECT_B3_REQ_NCCI(&CMSG) = i->NCCI;
 
3365
        _capi_put_cmsg(&CMSG);
 
3366
}
 
3367
 
 
3368
/*
 
3369
 * CAPI MANUFACTURER_IND
 
3370
 */
 
3371
static void capidev_handle_manufacturer_indication(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt *i)
 
3372
{
 
3373
        _cmsg CMSG2;
 
3374
        
 
3375
        MANUFACTURER_RESP_HEADER(&CMSG2, capi_ApplID, HEADER_MSGNUM(CMSG), 0);
 
3376
        MANUFACTURER_RESP_CONTROLLER(&CMSG2) = MANUFACTURER_IND_CONTROLLER(CMSG);
 
3377
        MANUFACTURER_RESP_MANUID(&CMSG2) = MANUFACTURER_IND_MANUID(CMSG);
 
3378
        _capi_put_cmsg(&CMSG2);
 
3379
        
 
3380
        return_on_no_interface("MANUFACTURER_IND");
 
3381
 
 
3382
        cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: Ignored MANUFACTURER_IND Id=0x%x \n",
 
3383
                i->vname, MANUFACTURER_IND_MANUID(CMSG));
 
3384
 
 
3385
        return;
 
3386
}
 
3387
 
 
3388
/*
 
3389
 * CAPI CONNECT_ACTIVE_IND
 
3390
 */
 
3391
static void capidev_handle_connect_active_indication(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt *i)
 
3392
{
 
3393
        _cmsg CMSG2;
 
3394
        
 
3395
        CONNECT_ACTIVE_RESP_HEADER(&CMSG2, capi_ApplID, HEADER_MSGNUM(CMSG), 0);
 
3396
        CONNECT_ACTIVE_RESP_PLCI(&CMSG2) = PLCI;
 
3397
        _capi_put_cmsg(&CMSG2);
 
3398
        
 
3399
        return_on_no_interface("CONNECT_ACTIVE_IND");
 
3400
 
 
3401
        if (i->state == CAPI_STATE_DISCONNECTING) {
 
3402
                cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: CONNECT_ACTIVE in DISCONNECTING.\n",
 
3403
                        i->vname);
 
3404
                return;
 
3405
        }
 
3406
 
 
3407
        i->state = CAPI_STATE_CONNECTED;
 
3408
 
 
3409
        if ((i->FaxState & CAPI_FAX_STATE_SENDMODE)) {
 
3410
                cc_start_b3(i);
 
3411
                return;
 
3412
        }
 
3413
 
 
3414
        if ((i->owner) && (i->FaxState & CAPI_FAX_STATE_ACTIVE)) {
 
3415
                ast_setstate(i->owner, AST_STATE_UP);
 
3416
                if (i->owner->cdr)
 
3417
                        ast_cdr_answer(i->owner->cdr);
 
3418
                return;
 
3419
        }
 
3420
        
 
3421
        /* normal processing */
 
3422
                            
 
3423
        if (!(i->isdnstate & CAPI_ISDN_STATE_B3_UP)) {
 
3424
                /* send a CONNECT_B3_REQ */
 
3425
                if (i->outgoing == 1) {
 
3426
                        /* outgoing call */
 
3427
                        cc_start_b3(i);
 
3428
                } else {
 
3429
                        /* incoming call */
 
3430
                        /* RESP already sent ... wait for CONNECT_B3_IND */
 
3431
                }
 
3432
        } else {
 
3433
                capi_signal_answer(i);
 
3434
        }
 
3435
        return;
 
3436
}
 
3437
 
 
3438
/*
 
3439
 * CAPI CONNECT_B3_ACTIVE_IND
 
3440
 */
 
3441
static void capidev_handle_connect_b3_active_indication(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt *i)
 
3442
{
 
3443
        _cmsg CMSG2;
 
3444
 
 
3445
        /* then send a CONNECT_B3_ACTIVE_RESP */
 
3446
        CONNECT_B3_ACTIVE_RESP_HEADER(&CMSG2, capi_ApplID, HEADER_MSGNUM(CMSG), 0);
 
3447
        CONNECT_B3_ACTIVE_RESP_NCCI(&CMSG2) = NCCI;
 
3448
        _capi_put_cmsg(&CMSG2);
 
3449
 
 
3450
        return_on_no_interface("CONNECT_ACTIVE_B3_IND");
 
3451
 
 
3452
        capi_controllers[i->controller]->nfreebchannels--;
 
3453
 
 
3454
        if (i->state == CAPI_STATE_DISCONNECTING) {
 
3455
                cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: CONNECT_B3_ACTIVE_IND during disconnect for NCCI %#x\n",
 
3456
                        i->vname, NCCI);
 
3457
                return;
 
3458
        }
 
3459
 
 
3460
        i->isdnstate |= CAPI_ISDN_STATE_B3_UP;
 
3461
        i->isdnstate &= ~CAPI_ISDN_STATE_B3_PEND;
 
3462
 
 
3463
        if (i->bproto == CC_BPROTO_RTP) {
 
3464
                i->isdnstate |= CAPI_ISDN_STATE_RTP;
 
3465
        } else {
 
3466
                i->isdnstate &= ~CAPI_ISDN_STATE_RTP;
 
3467
                i->B3q = (CAPI_MAX_B3_BLOCK_SIZE * 3);
 
3468
        }
 
3469
 
 
3470
        if ((i->FaxState & CAPI_FAX_STATE_SENDMODE)) {
 
3471
                cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: Start sending fax.\n",
 
3472
                        i->vname);
 
3473
                capidev_send_faxdata(i);
 
3474
        }
 
3475
 
 
3476
        if ((i->isdnstate & CAPI_ISDN_STATE_B3_CHANGE)) {
 
3477
                i->isdnstate &= ~CAPI_ISDN_STATE_B3_CHANGE;
 
3478
                cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: B3 protocol changed.\n",
 
3479
                        i->vname);
 
3480
                return;
 
3481
        }
 
3482
 
 
3483
        if (!i->owner) {
 
3484
                cc_log(LOG_ERROR, "%s: No channel for interface!\n",
 
3485
                        i->vname);
 
3486
                return;
 
3487
        }
 
3488
 
 
3489
        if (i->FaxState & CAPI_FAX_STATE_ACTIVE) {
 
3490
                cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: Fax connection, no EC/DTMF\n",
 
3491
                        i->vname);
 
3492
        } else {
 
3493
                capi_echo_canceller(i->owner, EC_FUNCTION_ENABLE);
 
3494
                capi_detect_dtmf(i->owner, 1);
 
3495
        }
 
3496
 
 
3497
        if (i->state == CAPI_STATE_CONNECTED) {
 
3498
                capi_signal_answer(i);
 
3499
        }
 
3500
        return;
 
3501
}
 
3502
 
 
3503
/*
 
3504
 * CAPI DISCONNECT_B3_IND
 
3505
 */
 
3506
static void capidev_handle_disconnect_b3_indication(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt *i)
 
3507
{
 
3508
        _cmsg CMSG2;
 
3509
 
 
3510
        DISCONNECT_B3_RESP_HEADER(&CMSG2, capi_ApplID, HEADER_MSGNUM(CMSG), 0);
 
3511
        DISCONNECT_B3_RESP_NCCI(&CMSG2) = NCCI;
 
3512
        _capi_put_cmsg(&CMSG2);
 
3513
 
 
3514
        return_on_no_interface("DISCONNECT_B3_IND");
 
3515
 
 
3516
        i->isdnstate &= ~(CAPI_ISDN_STATE_B3_UP | CAPI_ISDN_STATE_B3_PEND);
 
3517
 
 
3518
        i->reasonb3 = DISCONNECT_B3_IND_REASON_B3(CMSG);
 
3519
        i->NCCI = 0;
 
3520
 
 
3521
        if ((i->FaxState & CAPI_FAX_STATE_ACTIVE) && (i->owner)) {
 
3522
                char buffer[CAPI_MAX_STRING];
 
3523
                char *infostring;
 
3524
                unsigned char *ncpi = (unsigned char *)DISCONNECT_B3_IND_NCPI(CMSG);
 
3525
                /* if we have fax infos, set them as variables */
 
3526
                snprintf(buffer, CAPI_MAX_STRING-1, "%d", i->reasonb3);
 
3527
                pbx_builtin_setvar_helper(i->owner, "FAXREASON", buffer);
 
3528
                if (i->reasonb3 == 0) {
 
3529
                        pbx_builtin_setvar_helper(i->owner, "FAXREASONTEXT", "OK");
 
3530
                } else if ((infostring = capi_info_string(i->reasonb3)) != NULL) {
 
3531
                        pbx_builtin_setvar_helper(i->owner, "FAXREASONTEXT", infostring);
 
3532
                } else {
 
3533
                        pbx_builtin_setvar_helper(i->owner, "FAXREASONTEXT", "");
 
3534
                }
 
3535
                if (ncpi) {
 
3536
                        snprintf(buffer, CAPI_MAX_STRING-1, "%d", read_capi_word(&ncpi[1]));
 
3537
                        pbx_builtin_setvar_helper(i->owner, "FAXRATE", buffer);
 
3538
                        snprintf(buffer, CAPI_MAX_STRING-1, "%d", read_capi_word(&ncpi[3]));
 
3539
                        pbx_builtin_setvar_helper(i->owner, "FAXRESOLUTION", buffer);
 
3540
                        snprintf(buffer, CAPI_MAX_STRING-1, "%d", read_capi_word(&ncpi[5]));
 
3541
                        pbx_builtin_setvar_helper(i->owner, "FAXFORMAT", buffer);
 
3542
                        snprintf(buffer, CAPI_MAX_STRING-1, "%d", read_capi_word(&ncpi[7]));
 
3543
                        pbx_builtin_setvar_helper(i->owner, "FAXPAGES", buffer);
 
3544
                        memcpy(buffer, &ncpi[10], ncpi[9]);
 
3545
                        buffer[ncpi[9]] = 0;
 
3546
                        pbx_builtin_setvar_helper(i->owner, "FAXID", buffer);
 
3547
                }
 
3548
        }
 
3549
 
 
3550
        if ((i->state == CAPI_STATE_DISCONNECTING) ||
 
3551
            ((!(i->isdnstate & CAPI_ISDN_STATE_B3_SELECT)) &&
 
3552
             (i->FaxState & CAPI_FAX_STATE_SENDMODE))) {
 
3553
                /* active disconnect */
 
3554
                DISCONNECT_REQ_HEADER(&CMSG2, capi_ApplID, get_capi_MessageNumber(), 0);
 
3555
                DISCONNECT_REQ_PLCI(&CMSG2) = PLCI;
 
3556
                _capi_put_cmsg(&CMSG2);
 
3557
        }
 
3558
 
 
3559
        capi_controllers[i->controller]->nfreebchannels++;
 
3560
}
 
3561
 
 
3562
/*
 
3563
 * CAPI CONNECT_B3_IND
 
3564
 */
 
3565
static void capidev_handle_connect_b3_indication(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt *i)
 
3566
{
 
3567
        _cmsg CMSG2;
 
3568
 
 
3569
        /* then send a CONNECT_B3_RESP */
 
3570
        CONNECT_B3_RESP_HEADER(&CMSG2, capi_ApplID, HEADER_MSGNUM(CMSG), 0);
 
3571
        CONNECT_B3_RESP_NCCI(&CMSG2) = NCCI;
 
3572
        CONNECT_B3_RESP_REJECT(&CMSG2) = 0;
 
3573
        CONNECT_B3_RESP_NCPI(&CMSG2) = capi_rtp_ncpi(i);
 
3574
        _capi_put_cmsg(&CMSG2);
 
3575
 
 
3576
        return_on_no_interface("CONNECT_B3_IND");
 
3577
 
 
3578
        i->NCCI = NCCI;
 
3579
 
 
3580
        return;
 
3581
}
 
3582
 
 
3583
/*
 
3584
 * CAPI DISCONNECT_IND
 
3585
 */
 
3586
static void capidev_handle_disconnect_indication(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt *i)
 
3587
{
 
3588
        _cmsg CMSG2;
 
3589
        struct ast_frame fr = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP, };
 
3590
        int state;
 
3591
 
 
3592
        DISCONNECT_RESP_HEADER(&CMSG2, capi_ApplID, HEADER_MSGNUM(CMSG) , 0);
 
3593
        DISCONNECT_RESP_PLCI(&CMSG2) = PLCI;
 
3594
        _capi_put_cmsg(&CMSG2);
 
3595
        
 
3596
        show_capi_info(i, DISCONNECT_IND_REASON(CMSG));
 
3597
 
 
3598
        return_on_no_interface("DISCONNECT_IND");
 
3599
 
 
3600
        state = i->state;
 
3601
        i->state = CAPI_STATE_DISCONNECTED;
 
3602
 
 
3603
        i->reason = DISCONNECT_IND_REASON(CMSG);
 
3604
 
 
3605
        if ((i->owner) && (i->owner->hangupcause == 0)) {
 
3606
                /* set hangupcause, in case there is no 
 
3607
                 * "cause" information element:
 
3608
                 */
 
3609
                i->owner->hangupcause =
 
3610
                        ((i->reason & 0xFF00) == 0x3400) ?
 
3611
                        i->reason & 0x7F : AST_CAUSE_NORMAL_CLEARING;
 
3612
        }
 
3613
 
 
3614
        if (i->FaxState & CAPI_FAX_STATE_ACTIVE) {
 
3615
                /* in capiFax */
 
3616
                switch (i->reason) {
 
3617
                case 0x3400:
 
3618
                case 0x3490:
 
3619
                case 0x349f:
 
3620
                        if (i->reasonb3 != 0)
 
3621
                                i->FaxState |= CAPI_FAX_STATE_ERROR;
 
3622
                        break;
 
3623
                default:
 
3624
                        i->FaxState |= CAPI_FAX_STATE_ERROR;
 
3625
                }
 
3626
                i->FaxState &= ~CAPI_FAX_STATE_ACTIVE;
 
3627
        }
 
3628
 
 
3629
        if ((i->owner) &&
 
3630
            ((state == CAPI_STATE_DID) || (state == CAPI_STATE_INCALL)) &&
 
3631
            (!(i->isdnstate & CAPI_ISDN_STATE_PBX))) {
 
3632
                /* the pbx was not started yet */
 
3633
                cc_verbose(4, 1, VERBOSE_PREFIX_3 "%s: DISCONNECT_IND on incoming without pbx, doing hangup.\n",
 
3634
                        i->vname);
 
3635
                capi_channel_task(i->owner, CAPI_CHANNEL_TASK_HANGUP); 
 
3636
                return;
 
3637
        }
 
3638
 
 
3639
        if (DISCONNECT_IND_REASON(CMSG) == 0x34a2) {
 
3640
                fr.subclass = AST_CONTROL_CONGESTION;
 
3641
        }
 
3642
 
 
3643
        if (state == CAPI_STATE_DISCONNECTING) {
 
3644
                interface_cleanup(i);
 
3645
        } else {
 
3646
                local_queue_frame(i, &fr);
 
3647
        }
 
3648
        return;
 
3649
}
 
3650
 
 
3651
/*
 
3652
 * CAPI CONNECT_IND
 
3653
 */
 
3654
static void capidev_handle_connect_indication(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt **interface)
 
3655
{
 
3656
        struct capi_pvt *i;
 
3657
        _cmsg CMSG2;
 
3658
        char *DNID;
 
3659
        char *CID;
 
3660
        int callernplan = 0, callednplan = 0;
 
3661
        int controller = 0;
 
3662
        char *msn;
 
3663
        char buffer[CAPI_MAX_STRING];
 
3664
        char buffer_r[CAPI_MAX_STRING];
 
3665
        char *buffer_rp = buffer_r;
 
3666
        char *magicmsn = "*\0";
 
3667
        char *emptydnid = "\0";
 
3668
        int callpres = 0;
 
3669
        char bchannelinfo[2] = { '0', 0 };
 
3670
 
 
3671
        if (*interface) {
 
3672
            /* chan_capi does not support 
 
3673
             * double connect indications !
 
3674
             * (This is used to update 
 
3675
             *  telephone numbers and 
 
3676
             *  other information)
 
3677
             */
 
3678
                return;
 
3679
        }
 
3680
 
 
3681
        DNID = capi_number(CONNECT_IND_CALLEDPARTYNUMBER(CMSG), 1);
 
3682
        if (!DNID) {
 
3683
                DNID = emptydnid;
 
3684
        }
 
3685
        if (CONNECT_IND_CALLEDPARTYNUMBER(CMSG)[0] > 1) {
 
3686
                callednplan = (CONNECT_IND_CALLEDPARTYNUMBER(CMSG)[1] & 0x7f);
 
3687
        }
 
3688
 
 
3689
        CID = capi_number(CONNECT_IND_CALLINGPARTYNUMBER(CMSG), 2);
 
3690
        if (CONNECT_IND_CALLINGPARTYNUMBER(CMSG)[0] > 1) {
 
3691
                callernplan = (CONNECT_IND_CALLINGPARTYNUMBER(CMSG)[1] & 0x7f);
 
3692
                callpres = (CONNECT_IND_CALLINGPARTYNUMBER(CMSG)[2] & 0x63);
 
3693
        }
 
3694
        controller = PLCI & 0xff;
 
3695
        
 
3696
        cc_verbose(1, 1, VERBOSE_PREFIX_3 "CONNECT_IND (PLCI=%#x,DID=%s,CID=%s,CIP=%#x,CONTROLLER=%#x)\n",
 
3697
                PLCI, DNID, CID, CONNECT_IND_CIPVALUE(CMSG), controller);
 
3698
 
 
3699
        if (CONNECT_IND_BCHANNELINFORMATION(CMSG)) {
 
3700
                bchannelinfo[0] = CONNECT_IND_BCHANNELINFORMATION(CMSG)[1] + '0';
 
3701
        }
 
3702
 
 
3703
        /* well...somebody is calling us. let's set up a channel */
 
3704
        cc_mutex_lock(&iflock);
 
3705
        for (i = iflist; i; i = i->next) {
 
3706
                if (i->owner) {
 
3707
                        /* has already owner */
 
3708
                        continue;
 
3709
                }
 
3710
                if (i->controller != controller) {
 
3711
                        continue;
 
3712
                }
 
3713
                if (i->channeltype == CAPI_CHANNELTYPE_B) {
 
3714
                        if (bchannelinfo[0] != '0')
 
3715
                                continue;
 
3716
                } else {
 
3717
                        if (bchannelinfo[0] == '0')
 
3718
                                continue;
 
3719
                }
 
3720
                cc_copy_string(buffer, i->incomingmsn, sizeof(buffer));
 
3721
                for (msn = strtok_r(buffer, ",", &buffer_rp); msn; msn = strtok_r(NULL, ",", &buffer_rp)) {
 
3722
                        if (!strlen(DNID)) {
 
3723
                                /* if no DNID, only accept if '*' was specified */
 
3724
                                if (strncasecmp(msn, magicmsn, strlen(msn))) {
 
3725
                                        continue;
 
3726
                                }
 
3727
                                cc_copy_string(i->dnid, emptydnid, sizeof(i->dnid));
 
3728
                        } else {
 
3729
                                /* make sure the number match exactly or may match on ptp mode */
 
3730
                                cc_verbose(4, 1, VERBOSE_PREFIX_4 "%s: msn='%s' DNID='%s' %s\n",
 
3731
                                        i->vname, msn, DNID,
 
3732
                                        (i->isdnmode == CAPI_ISDNMODE_MSN)?"MSN":"DID");
 
3733
                                if ((strcasecmp(msn, DNID)) &&
 
3734
                                   ((i->isdnmode == CAPI_ISDNMODE_MSN) ||
 
3735
                                    (strlen(msn) >= strlen(DNID)) ||
 
3736
                                    (strncasecmp(msn, DNID, strlen(msn)))) &&
 
3737
                                   (strncasecmp(msn, magicmsn, strlen(msn)))) {
 
3738
                                        continue;
 
3739
                                }
 
3740
                                cc_copy_string(i->dnid, DNID, sizeof(i->dnid));
 
3741
                        }
 
3742
                        if (CID != NULL) {
 
3743
                                if ((callernplan & 0x70) == CAPI_ETSI_NPLAN_NATIONAL)
 
3744
                                        snprintf(i->cid, (sizeof(i->cid)-1), "%s%s%s",
 
3745
                                                i->prefix, capi_national_prefix, CID);
 
3746
                                else if ((callernplan & 0x70) == CAPI_ETSI_NPLAN_INTERNAT)
 
3747
                                        snprintf(i->cid, (sizeof(i->cid)-1), "%s%s%s",
 
3748
                                                i->prefix, capi_international_prefix, CID);
 
3749
                                else
 
3750
                                        snprintf(i->cid, (sizeof(i->cid)-1), "%s%s",
 
3751
                                                i->prefix, CID);
 
3752
                        } else {
 
3753
                                cc_copy_string(i->cid, emptyid, sizeof(i->cid));
 
3754
                        }
 
3755
                        i->cip = CONNECT_IND_CIPVALUE(CMSG);
 
3756
                        i->PLCI = PLCI;
 
3757
                        i->MessageNumber = HEADER_MSGNUM(CMSG);
 
3758
                        i->cid_ton = callernplan;
 
3759
 
 
3760
                        capi_new(i, AST_STATE_DOWN);
 
3761
                        if (i->isdnmode == CAPI_ISDNMODE_DID) {
 
3762
                                i->state = CAPI_STATE_DID;
 
3763
                        } else {
 
3764
                                i->state = CAPI_STATE_INCALL;
 
3765
                        }
 
3766
 
 
3767
                        if (!i->owner) {
 
3768
                                interface_cleanup(i);
 
3769
                                break;
 
3770
                        }
 
3771
                        i->owner->transfercapability = cip2tcap(i->cip);
 
3772
                        if (tcap_is_digital(i->owner->transfercapability)) {
 
3773
                                i->bproto = CC_BPROTO_TRANSPARENT;
 
3774
                        }
 
3775
                        i->owner->cid.cid_pres = callpres;
 
3776
                        cc_verbose(3, 0, VERBOSE_PREFIX_2 "%s: Incoming call '%s' -> '%s'\n",
 
3777
                                i->vname, i->cid, i->dnid);
 
3778
 
 
3779
                        *interface = i;
 
3780
                        cc_mutex_unlock(&iflock);
 
3781
                        cc_mutex_lock(&i->lock);
 
3782
                
 
3783
                        pbx_builtin_setvar_helper(i->owner, "TRANSFERCAPABILITY", transfercapability2str(i->owner->transfercapability));
 
3784
                        pbx_builtin_setvar_helper(i->owner, "BCHANNELINFO", bchannelinfo);
 
3785
                        sprintf(buffer, "%d", callednplan);
 
3786
                        pbx_builtin_setvar_helper(i->owner, "CALLEDTON", buffer);
 
3787
                        /*
 
3788
                        pbx_builtin_setvar_helper(i->owner, "CALLINGSUBADDRESS",
 
3789
                                CONNECT_IND_CALLINGPARTYSUBADDRESS(CMSG));
 
3790
                        pbx_builtin_setvar_helper(i->owner, "CALLEDSUBADDRESS",
 
3791
                                CONNECT_IND_CALLEDPARTYSUBADDRESS(CMSG));
 
3792
                        pbx_builtin_setvar_helper(i->owner, "USERUSERINFO",
 
3793
                                CONNECT_IND_USERUSERDATA(CMSG));
 
3794
                        */
 
3795
                        /* TODO : set some more variables on incoming call */
 
3796
                        /*
 
3797
                        pbx_builtin_setvar_helper(i->owner, "ANI2", buffer);
 
3798
                        pbx_builtin_setvar_helper(i->owner, "SECONDCALLERID", buffer);
 
3799
                        */
 
3800
                        if ((i->isdnmode == CAPI_ISDNMODE_MSN) && (i->immediate)) {
 
3801
                                /* if we don't want to wait for SETUP/SENDING-COMPLETE in MSN mode */
 
3802
                                start_pbx_on_match(i, PLCI, HEADER_MSGNUM(CMSG));
 
3803
                        }
 
3804
                        return;
 
3805
                }
 
3806
        }
 
3807
        cc_mutex_unlock(&iflock);
 
3808
 
 
3809
        /* obviously we are not called...so tell capi to ignore this call */
 
3810
 
 
3811
        if (capidebug) {
 
3812
                cc_log(LOG_WARNING, "did not find device for msn = %s\n", DNID);
 
3813
        }
 
3814
        
 
3815
        CONNECT_RESP_HEADER(&CMSG2, capi_ApplID, HEADER_MSGNUM(CMSG), 0);
 
3816
        CONNECT_RESP_PLCI(&CMSG2) = CONNECT_IND_PLCI(CMSG);
 
3817
        CONNECT_RESP_REJECT(&CMSG2) = 1; /* ignore */
 
3818
        _capi_put_cmsg(&CMSG2);
 
3819
        return;
 
3820
}
 
3821
 
 
3822
/*
 
3823
 * CAPI FACILITY_CONF
 
3824
 */
 
3825
static void capidev_handle_facility_confirmation(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt *i)
 
3826
{
 
3827
        int selector;
 
3828
 
 
3829
        if (i == NULL)
 
3830
                return;
 
3831
 
 
3832
        selector = FACILITY_CONF_FACILITYSELECTOR(CMSG);
 
3833
 
 
3834
        if (selector == FACILITYSELECTOR_DTMF) {
 
3835
                cc_verbose(2, 1, VERBOSE_PREFIX_4 "%s: DTMF conf(PLCI=%#x)\n",
 
3836
                        i->vname, PLCI);
 
3837
                return;
 
3838
        }
 
3839
        if (selector == i->ecSelector) {
 
3840
                if (FACILITY_CONF_INFO(CMSG)) {
 
3841
                        cc_verbose(2, 0, VERBOSE_PREFIX_3 "%s: Error setting up echo canceller (PLCI=%#x)\n",
 
3842
                                i->vname, PLCI);
 
3843
                        return;
 
3844
                }
 
3845
                if (FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(CMSG)[1] == EC_FUNCTION_DISABLE) {
 
3846
                        cc_verbose(3, 0, VERBOSE_PREFIX_3 "%s: Echo canceller successfully disabled (PLCI=%#x)\n",
 
3847
                                i->vname, PLCI);
 
3848
                } else {
 
3849
                        cc_verbose(3, 0, VERBOSE_PREFIX_3 "%s: Echo canceller successfully set up (PLCI=%#x)\n",
 
3850
                                i->vname, PLCI);
 
3851
                }
 
3852
                return;
 
3853
        }
 
3854
        if (selector == FACILITYSELECTOR_SUPPLEMENTARY) {
 
3855
                /* HOLD */
 
3856
                if ((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(CMSG)[1] == 0x2) &&
 
3857
                    (FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(CMSG)[2] == 0x0) &&
 
3858
                    ((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(CMSG)[4] != 0x0) ||
 
3859
                     (FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(CMSG)[5] != 0x0))) {
 
3860
                        cc_verbose(2, 0, VERBOSE_PREFIX_3 "%s: Call on hold (PLCI=%#x)\n",
 
3861
                                i->vname, PLCI);
 
3862
                }
 
3863
                return;
 
3864
        }
 
3865
        if (selector == FACILITYSELECTOR_LINE_INTERCONNECT) {
 
3866
                if ((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(CMSG)[1] == 0x1) &&
 
3867
                    (FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(CMSG)[2] == 0x0)) {
 
3868
                        /* enable */
 
3869
                        if (FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(CMSG)[0] > 12) {
 
3870
                                show_capi_info(i, read_capi_word(&FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(CMSG)[12]));
 
3871
                        }
 
3872
                } else {
 
3873
                        /* disable */
 
3874
                        if (FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(CMSG)[0] > 12) {
 
3875
                                show_capi_info(i, read_capi_word(&FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(CMSG)[12]));
 
3876
                        }
 
3877
                }
 
3878
                return;
 
3879
        }
 
3880
        cc_log(LOG_ERROR, "%s: unhandled FACILITY_CONF 0x%x\n",
 
3881
                i->vname, FACILITY_CONF_FACILITYSELECTOR(CMSG));
 
3882
}
 
3883
 
 
3884
/*
 
3885
 * show error in confirmation
 
3886
 */
 
3887
static void show_capi_conf_error(struct capi_pvt *i, 
 
3888
                                 unsigned int PLCI, u_int16_t wInfo, 
 
3889
                                 u_int16_t wCmd)
 
3890
{
 
3891
        const char *name = channeltype;
 
3892
 
 
3893
        if (i)
 
3894
                name = i->vname;
 
3895
        
 
3896
        if ((wCmd == CAPI_P_CONF(ALERT)) && (wInfo == 0x0003)) {
 
3897
                /* Alert already sent by another application */
 
3898
                return;
 
3899
        }
 
3900
                
 
3901
        if (wInfo == 0x2002) {
 
3902
                cc_verbose(1, 1, VERBOSE_PREFIX_3 "%s: "
 
3903
                               "0x%x (wrong state) PLCI=0x%x "
 
3904
                               "Command=%s,0x%04x\n",
 
3905
                               name, wInfo, PLCI, capi_command_to_string(wCmd), wCmd);
 
3906
        } else {
 
3907
                cc_log(LOG_WARNING, "%s: conf_error 0x%04x "
 
3908
                        "PLCI=0x%x Command=%s,0x%04x\n",
 
3909
                        name, wInfo, PLCI, capi_command_to_string(wCmd), wCmd);
 
3910
        }
 
3911
        return;
 
3912
}
 
3913
 
 
3914
/*
 
3915
 * check special conditions, wake waiting threads and send outstanding commands
 
3916
 * for the given interface
 
3917
 */
 
3918
static void capidev_post_handling(struct capi_pvt *i, _cmsg *CMSG)
 
3919
{
 
3920
        unsigned short capicommand = CAPICMD(CMSG->Command, CMSG->Subcommand);
 
3921
 
 
3922
        if ((i->waitevent == CAPI_WAITEVENT_B3_UP) &&
 
3923
            ((i->isdnstate & CAPI_ISDN_STATE_B3_UP))) {
 
3924
                i->waitevent = 0;
 
3925
                ast_cond_signal(&i->event_trigger);
 
3926
                cc_verbose(4, 1, "%s: found and signal for b3 up state.\n",
 
3927
                        i->vname);
 
3928
                return;
 
3929
        }
 
3930
        if ((i->waitevent == CAPI_WAITEVENT_B3_DOWN) &&
 
3931
            (!(i->isdnstate & (CAPI_ISDN_STATE_B3_UP | CAPI_ISDN_STATE_B3_PEND)))) {
 
3932
                i->waitevent = 0;
 
3933
                ast_cond_signal(&i->event_trigger);
 
3934
                cc_verbose(4, 1, "%s: found and signal for b3 down state.\n",
 
3935
                        i->vname);
 
3936
                return;
 
3937
        }
 
3938
        if ((i->waitevent == CAPI_WAITEVENT_FAX_FINISH) &&
 
3939
            (!(i->FaxState & CAPI_FAX_STATE_ACTIVE))) {
 
3940
                i->waitevent = 0;
 
3941
                ast_cond_signal(&i->event_trigger);
 
3942
                cc_verbose(4, 1, "%s: found and signal for finished fax state.\n",
 
3943
                        i->vname);
 
3944
                return;
 
3945
        }
 
3946
        if ((i->waitevent == CAPI_WAITEVENT_ANSWER_FINISH) &&
 
3947
            (i->state != CAPI_STATE_ANSWERING)) {
 
3948
                i->waitevent = 0;
 
3949
                ast_cond_signal(&i->event_trigger);
 
3950
                cc_verbose(4, 1, "%s: found and signal for finished ANSWER state.\n",
 
3951
                        i->vname);
 
3952
                return;
 
3953
        }
 
3954
        if (i->waitevent == capicommand) {
 
3955
                i->waitevent = 0;
 
3956
                ast_cond_signal(&i->event_trigger);
 
3957
                cc_verbose(4, 1, "%s: found and signal for %s\n",
 
3958
                        i->vname, capi_cmd2str(CMSG->Command, CMSG->Subcommand));
 
3959
                return;
 
3960
        }
 
3961
}
 
3962
 
 
3963
/*
 
3964
 * handle CAPI msg
 
3965
 */
 
3966
static void capidev_handle_msg(_cmsg *CMSG)
 
3967
{
 
3968
        unsigned int NCCI = HEADER_CID(CMSG);
 
3969
        unsigned int PLCI = (NCCI & 0xffff);
 
3970
        unsigned short wCmd = HEADER_CMD(CMSG);
 
3971
        unsigned short wMsgNum = HEADER_MSGNUM(CMSG);
 
3972
        unsigned short wInfo = 0xffff;
 
3973
        struct capi_pvt *i = find_interface_by_plci(PLCI);
 
3974
 
 
3975
        if ((wCmd == CAPI_P_IND(DATA_B3)) ||
 
3976
            (wCmd == CAPI_P_CONF(DATA_B3))) {
 
3977
                cc_verbose(7, 1, "%s\n", capi_cmsg2str(CMSG));
 
3978
        } else {
 
3979
                cc_verbose(4, 1, "%s\n", capi_cmsg2str(CMSG));
 
3980
        }
 
3981
 
 
3982
        if (i != NULL)
 
3983
                cc_mutex_lock(&i->lock);
 
3984
 
 
3985
        /* main switch table */
 
3986
 
 
3987
        switch (wCmd) {
 
3988
 
 
3989
          /*
 
3990
           * CAPI indications
 
3991
           */
 
3992
        case CAPI_P_IND(CONNECT):
 
3993
                capidev_handle_connect_indication(CMSG, PLCI, NCCI, &i);
 
3994
                break;
 
3995
        case CAPI_P_IND(DATA_B3):
 
3996
                capidev_handle_data_b3_indication(CMSG, PLCI, NCCI, i);
 
3997
                break;
 
3998
        case CAPI_P_IND(CONNECT_B3):
 
3999
                capidev_handle_connect_b3_indication(CMSG, PLCI, NCCI, i);
 
4000
                break;
 
4001
        case CAPI_P_IND(CONNECT_B3_ACTIVE):
 
4002
                capidev_handle_connect_b3_active_indication(CMSG, PLCI, NCCI, i);
 
4003
                break;
 
4004
        case CAPI_P_IND(DISCONNECT_B3):
 
4005
                capidev_handle_disconnect_b3_indication(CMSG, PLCI, NCCI, i);
 
4006
                break;
 
4007
        case CAPI_P_IND(DISCONNECT):
 
4008
                capidev_handle_disconnect_indication(CMSG, PLCI, NCCI, i);
 
4009
                break;
 
4010
        case CAPI_P_IND(FACILITY):
 
4011
                capidev_handle_facility_indication(CMSG, PLCI, NCCI, i);
 
4012
                break;
 
4013
        case CAPI_P_IND(INFO):
 
4014
                capidev_handle_info_indication(CMSG, PLCI, NCCI, i);
 
4015
                break;
 
4016
        case CAPI_P_IND(CONNECT_ACTIVE):
 
4017
                capidev_handle_connect_active_indication(CMSG, PLCI, NCCI, i);
 
4018
                break;
 
4019
        case CAPI_P_IND(MANUFACTURER):
 
4020
                capidev_handle_manufacturer_indication(CMSG, PLCI, NCCI, i);
 
4021
                break;
 
4022
 
 
4023
          /*
 
4024
           * CAPI confirmations
 
4025
           */
 
4026
 
 
4027
        case CAPI_P_CONF(FACILITY):
 
4028
                wInfo = FACILITY_CONF_INFO(CMSG);
 
4029
                capidev_handle_facility_confirmation(CMSG, PLCI, NCCI, i);
 
4030
                break;
 
4031
        case CAPI_P_CONF(CONNECT):
 
4032
                wInfo = CONNECT_CONF_INFO(CMSG);
 
4033
                if (i) {
 
4034
                        cc_log(LOG_ERROR, "CAPI: CONNECT_CONF for already "
 
4035
                                "defined interface received\n");
 
4036
                        break;
 
4037
                }
 
4038
                i = find_interface_by_msgnum(wMsgNum);
 
4039
                if ((i == NULL) || (!i->owner))
 
4040
                        break;
 
4041
                cc_verbose(1, 1, VERBOSE_PREFIX_3 "%s: received CONNECT_CONF PLCI = %#x\n",
 
4042
                        i->vname, PLCI);
 
4043
                if (wInfo == 0) {
 
4044
                        i->PLCI = PLCI;
 
4045
                } else {
 
4046
                        /* error in connect, so set correct state and signal busy */
 
4047
                        i->state = CAPI_STATE_DISCONNECTED;
 
4048
                        struct ast_frame fr = { AST_FRAME_CONTROL, AST_CONTROL_BUSY, };
 
4049
                        local_queue_frame(i, &fr);
 
4050
                }
 
4051
                break;
 
4052
        case CAPI_P_CONF(CONNECT_B3):
 
4053
                wInfo = CONNECT_B3_CONF_INFO(CMSG);
 
4054
                if(i == NULL) break;
 
4055
                if (wInfo == 0) {
 
4056
                        i->NCCI = NCCI;
 
4057
                } else {
 
4058
                        i->isdnstate &= ~(CAPI_ISDN_STATE_B3_UP | CAPI_ISDN_STATE_B3_PEND);
 
4059
                }
 
4060
                break;
 
4061
        case CAPI_P_CONF(ALERT):
 
4062
                wInfo = ALERT_CONF_INFO(CMSG);
 
4063
                if(i == NULL) break;
 
4064
                if (!i->owner) break;
 
4065
                if ((wInfo & 0xff00) == 0) {
 
4066
                        if (i->state != CAPI_STATE_DISCONNECTING) {
 
4067
                                i->state = CAPI_STATE_ALERTING;
 
4068
                                if (i->owner->_state == AST_STATE_RING) {
 
4069
                                        i->owner->rings = 1;
 
4070
                                }
 
4071
                        }
 
4072
                }
 
4073
                break;      
 
4074
        case CAPI_P_CONF(SELECT_B_PROTOCOL):
 
4075
                wInfo = SELECT_B_PROTOCOL_CONF_INFO(CMSG);
 
4076
                if(i == NULL) break;
 
4077
                if (!wInfo) {
 
4078
                        i->isdnstate &= ~CAPI_ISDN_STATE_B3_SELECT;
 
4079
                        if ((i->outgoing) && (i->FaxState & CAPI_FAX_STATE_SENDMODE)) {
 
4080
                                cc_start_b3(i);
 
4081
                        }
 
4082
                        if ((i->owner) && (i->FaxState & CAPI_FAX_STATE_ACTIVE)) {
 
4083
                                capi_echo_canceller(i->owner, EC_FUNCTION_DISABLE);
 
4084
                                capi_detect_dtmf(i->owner, 0);
 
4085
                        }
 
4086
                }
 
4087
                break;
 
4088
        case CAPI_P_CONF(DATA_B3):
 
4089
                wInfo = DATA_B3_CONF_INFO(CMSG);
 
4090
                if ((i) && (i->B3q > 0) && (i->isdnstate & CAPI_ISDN_STATE_RTP)) {
 
4091
                        i->B3q--;
 
4092
                }
 
4093
                if ((i) && (i->FaxState & CAPI_FAX_STATE_SENDMODE)) {
 
4094
                        capidev_send_faxdata(i);
 
4095
                }
 
4096
                break;
 
4097
 
 
4098
        case CAPI_P_CONF(DISCONNECT):
 
4099
                wInfo = DISCONNECT_CONF_INFO(CMSG);
 
4100
                break;
 
4101
 
 
4102
        case CAPI_P_CONF(DISCONNECT_B3):
 
4103
                wInfo = DISCONNECT_B3_CONF_INFO(CMSG);
 
4104
                break;
 
4105
 
 
4106
        case CAPI_P_CONF(LISTEN):
 
4107
                wInfo = LISTEN_CONF_INFO(CMSG);
 
4108
                break;
 
4109
 
 
4110
        case CAPI_P_CONF(INFO):
 
4111
                wInfo = INFO_CONF_INFO(CMSG);
 
4112
                break;
 
4113
 
 
4114
        default:
 
4115
                cc_log(LOG_ERROR, "CAPI: Command=%s,0x%04x",
 
4116
                        capi_command_to_string(wCmd), wCmd);
 
4117
                break;
 
4118
        }
 
4119
 
 
4120
        if (wInfo != 0xffff) {
 
4121
                if (wInfo) {
 
4122
                        show_capi_conf_error(i, PLCI, wInfo, wCmd);
 
4123
                }
 
4124
                show_capi_info(i, wInfo);
 
4125
        }
 
4126
 
 
4127
        if (i == NULL) {
 
4128
                cc_verbose(2, 1, VERBOSE_PREFIX_4
 
4129
                        "CAPI: Command=%s,0x%04x: no interface for PLCI="
 
4130
                        "%#x, MSGNUM=%#x!\n", capi_command_to_string(wCmd),
 
4131
                        wCmd, PLCI, wMsgNum);
 
4132
        } else {
 
4133
                capidev_post_handling(i, CMSG);
 
4134
                cc_mutex_unlock(&i->lock);
 
4135
        }
 
4136
 
 
4137
        return;
 
4138
}
 
4139
 
 
4140
/*
 
4141
 * deflect a call
 
4142
 */
 
4143
static int pbx_capi_call_deflect(struct ast_channel *c, char *param)
 
4144
{
 
4145
        struct capi_pvt *i = CC_CHANNEL_PVT(c);
 
4146
        _cmsg   CMSG;
 
4147
        char    fac[64];
 
4148
        int     res = 0;
 
4149
        char *number;
 
4150
        int numberlen;
 
4151
 
 
4152
        if (!param) {
 
4153
                cc_log(LOG_WARNING, "capi deflection requires an argument (destination phone number)\n");
 
4154
                return -1;
 
4155
        }
 
4156
        number = strsep(&param, "|");
 
4157
        numberlen = strlen(number);
 
4158
 
 
4159
        if (!numberlen) {
 
4160
                cc_log(LOG_WARNING, "capi deflection requires an argument (destination phone number)\n");
 
4161
                return -1;
 
4162
        }
 
4163
        if (numberlen > 35) {
 
4164
                cc_log(LOG_WARNING, "capi deflection does only support phone number up to 35 digits\n");
 
4165
                return -1;
 
4166
        }
 
4167
        if (!(capi_controllers[i->controller]->CD)) {
 
4168
                cc_log(LOG_NOTICE,"%s: CALL DEFLECT for %s not supported by controller.\n",
 
4169
                        i->vname, c->name);
 
4170
                return -1;
 
4171
        }
 
4172
 
 
4173
        cc_mutex_lock(&i->lock);
 
4174
 
 
4175
        if ((i->state != CAPI_STATE_INCALL) &&
 
4176
            (i->state != CAPI_STATE_DID) &&
 
4177
            (i->state != CAPI_STATE_ALERTING)) {
 
4178
                cc_mutex_unlock(&i->lock);
 
4179
                cc_log(LOG_WARNING, "wrong state of call for call deflection\n");
 
4180
                return -1;
 
4181
        }
 
4182
        if (i->state != CAPI_STATE_ALERTING) {
 
4183
                pbx_capi_alert(c);
 
4184
        }
 
4185
        
 
4186
        fac[0] = 0x0a + numberlen; /* length */
 
4187
        fac[1] = 0x0d; /* call deflection */
 
4188
        fac[2] = 0x00;
 
4189
        fac[3] = 0x07 + numberlen; /* struct len */
 
4190
        fac[4] = 0x01; /* display of own address allowed */
 
4191
        fac[5] = 0x00;
 
4192
        fac[6] = 0x03 + numberlen;
 
4193
        fac[7] = 0x00; /* type of facility number */
 
4194
        fac[8] = 0x00; /* number plan */
 
4195
        fac[9] = 0x00; /* presentation allowed */
 
4196
        fac[10 + numberlen] = 0x00; /* subaddress len */
 
4197
 
 
4198
        memcpy((unsigned char *)fac + 10, number, numberlen);
 
4199
 
 
4200
        FACILITY_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(),0);
 
4201
        FACILITY_REQ_PLCI(&CMSG) = i->PLCI;
 
4202
        FACILITY_REQ_FACILITYSELECTOR(&CMSG) = FACILITYSELECTOR_SUPPLEMENTARY;
 
4203
        FACILITY_REQ_FACILITYREQUESTPARAMETER(&CMSG) = (_cstruct)&fac;
 
4204
        
 
4205
        _capi_put_cmsg_wait_conf(i, &CMSG);
 
4206
 
 
4207
        cc_mutex_unlock(&i->lock);
 
4208
 
 
4209
        cc_verbose(2, 1, VERBOSE_PREFIX_3 "%s: sent FACILITY_REQ for CD PLCI = %#x\n",
 
4210
                i->vname, i->PLCI);
 
4211
 
 
4212
        return(res);
 
4213
}
 
4214
 
 
4215
/*
 
4216
 * retrieve a hold on call
 
4217
 */
 
4218
static int pbx_capi_retrieve(struct ast_channel *c, char *param)
 
4219
{
 
4220
        struct capi_pvt *i = CC_CHANNEL_PVT(c); 
 
4221
        _cmsg   CMSG;
 
4222
        char    fac[4];
 
4223
        unsigned int plci = 0;
 
4224
 
 
4225
        if (c->tech->type == channeltype) {
 
4226
                plci = i->onholdPLCI;
 
4227
        } else {
 
4228
                i = NULL;
 
4229
        }
 
4230
 
 
4231
        if (param) {
 
4232
                plci = (unsigned int)strtoul(param, NULL, 0);
 
4233
                cc_mutex_lock(&iflock);
 
4234
                for (i = iflist; i; i = i->next) {
 
4235
                        if (i->onholdPLCI == plci)
 
4236
                                break;
 
4237
                }
 
4238
                cc_mutex_unlock(&iflock);
 
4239
                if (!i) {
 
4240
                        plci = 0;
 
4241
                }
 
4242
        }
 
4243
 
 
4244
        if (!i) {
 
4245
                cc_log(LOG_WARNING, "%s is not valid or not on capi hold to retrieve!\n",
 
4246
                        c->name);
 
4247
                return 0;
 
4248
        }
 
4249
 
 
4250
        if ((i->state != CAPI_STATE_ONHOLD) &&
 
4251
            (i->isdnstate & CAPI_ISDN_STATE_HOLD)) {
 
4252
                int waitcount = 20;
 
4253
                while ((waitcount > 0) && (i->state != CAPI_STATE_ONHOLD)) {
 
4254
                        usleep(10000);
 
4255
                        waitcount--;
 
4256
                }
 
4257
        }
 
4258
 
 
4259
        if ((!plci) || (i->state != CAPI_STATE_ONHOLD)) {
 
4260
                cc_log(LOG_WARNING, "%s: 0x%x is not valid or not on hold to retrieve!\n",
 
4261
                        i->vname, plci);
 
4262
                return 0;
 
4263
        }
 
4264
        cc_verbose(2, 1, VERBOSE_PREFIX_4 "%s: using PLCI=%#x for retrieve\n",
 
4265
                i->vname, plci);
 
4266
 
 
4267
        if (!(capi_controllers[i->controller]->holdretrieve)) {
 
4268
                cc_log(LOG_NOTICE,"%s: RETRIEVE for %s not supported by controller.\n",
 
4269
                        i->vname, c->name);
 
4270
                return -1;
 
4271
        }
 
4272
 
 
4273
        fac[0] = 3;     /* len */
 
4274
        fac[1] = 0x03;  /* retrieve */
 
4275
        fac[2] = 0x00;
 
4276
        fac[3] = 0;     
 
4277
 
 
4278
        FACILITY_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(),0);
 
4279
        FACILITY_REQ_PLCI(&CMSG) = plci;
 
4280
        FACILITY_REQ_FACILITYSELECTOR(&CMSG) = FACILITYSELECTOR_SUPPLEMENTARY;
 
4281
        FACILITY_REQ_FACILITYREQUESTPARAMETER(&CMSG) = (_cstruct)&fac;
 
4282
 
 
4283
        _capi_put_cmsg(&CMSG);
 
4284
        cc_verbose(2, 1, VERBOSE_PREFIX_4 "%s: sent RETRIEVE for PLCI=%#x\n",
 
4285
                i->vname, plci);
 
4286
 
 
4287
        i->isdnstate &= ~CAPI_ISDN_STATE_HOLD;
 
4288
        pbx_builtin_setvar_helper(i->owner, "_CALLERHOLDID", NULL);
 
4289
 
 
4290
        return 0;
 
4291
}
 
4292
 
 
4293
/*
 
4294
 * explicit transfer a held call
 
4295
 */
 
4296
static int pbx_capi_ect(struct ast_channel *c, char *param)
 
4297
{
 
4298
        struct capi_pvt *i = CC_CHANNEL_PVT(c);
 
4299
        struct capi_pvt *ii = NULL;
 
4300
        _cmsg CMSG;
 
4301
        char fac[8];
 
4302
        const char *id;
 
4303
        unsigned int plci = 0;
 
4304
 
 
4305
        if ((id = pbx_builtin_getvar_helper(c, "CALLERHOLDID"))) {
 
4306
                plci = (unsigned int)strtoul(id, NULL, 0);
 
4307
        }
 
4308
        
 
4309
        if (param) {
 
4310
                plci = (unsigned int)strtoul(param, NULL, 0);
 
4311
        }
 
4312
 
 
4313
        if (!plci) {
 
4314
                cc_log(LOG_WARNING, "%s: No id for ECT !\n", i->vname);
 
4315
                return -1;
 
4316
        }
 
4317
 
 
4318
        cc_mutex_lock(&iflock);
 
4319
        for (ii = iflist; ii; ii = ii->next) {
 
4320
                if (ii->onholdPLCI == plci)
 
4321
                        break;
 
4322
        }
 
4323
        cc_mutex_unlock(&iflock);
 
4324
 
 
4325
        if (!ii) {
 
4326
                cc_log(LOG_WARNING, "%s: 0x%x is not on hold !\n",
 
4327
                        i->vname, plci);
 
4328
                return -1;
 
4329
        }
 
4330
 
 
4331
        cc_verbose(2, 1, VERBOSE_PREFIX_4 "%s: using PLCI=%#x for ECT\n",
 
4332
                i->vname, plci);
 
4333
 
 
4334
        if (!(capi_controllers[i->controller]->ECT)) {
 
4335
                cc_log(LOG_WARNING, "%s: ECT for %s not supported by controller.\n",
 
4336
                        i->vname, c->name);
 
4337
                return -1;
 
4338
        }
 
4339
 
 
4340
        if (!(ii->isdnstate & CAPI_ISDN_STATE_HOLD)) {
 
4341
                cc_log(LOG_WARNING, "%s: PLCI %#x (%s) is not on hold for ECT\n",
 
4342
                        i->vname, plci, ii->vname);
 
4343
                return -1;
 
4344
        }
 
4345
 
 
4346
        cc_disconnect_b3(i, 1);
 
4347
 
 
4348
        if (i->state != CAPI_STATE_CONNECTED) {
 
4349
                cc_log(LOG_WARNING, "%s: destination not connected for ECT\n",
 
4350
                        i->vname);
 
4351
                return -1;
 
4352
        }
 
4353
 
 
4354
        fac[0] = 7;     /* len */
 
4355
        fac[1] = 0x06;  /* ECT (function) */
 
4356
        fac[2] = 0x00;
 
4357
        fac[3] = 4;     /* len / sservice specific parameter , cstruct */
 
4358
        write_capi_dword(&(fac[4]), plci);
 
4359
 
 
4360
        FACILITY_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(), 0);
 
4361
        FACILITY_REQ_CONTROLLER(&CMSG) = i->controller;
 
4362
        FACILITY_REQ_PLCI(&CMSG) = plci; /* implicit ECT */
 
4363
        FACILITY_REQ_FACILITYSELECTOR(&CMSG) = FACILITYSELECTOR_SUPPLEMENTARY;
 
4364
        FACILITY_REQ_FACILITYREQUESTPARAMETER(&CMSG) = (_cstruct)&fac;
 
4365
 
 
4366
        cc_mutex_lock(&ii->lock);
 
4367
        _capi_put_cmsg_wait_conf(ii, &CMSG);
 
4368
        
 
4369
        ii->isdnstate &= ~CAPI_ISDN_STATE_HOLD;
 
4370
        ii->isdnstate |= CAPI_ISDN_STATE_ECT;
 
4371
        i->isdnstate |= CAPI_ISDN_STATE_ECT;
 
4372
        
 
4373
        cc_mutex_unlock(&ii->lock);
 
4374
 
 
4375
        cc_verbose(2, 1, VERBOSE_PREFIX_4 "%s: sent ECT for PLCI=%#x to PLCI=%#x\n",
 
4376
                i->vname, plci, i->PLCI);
 
4377
 
 
4378
        return 0;
 
4379
}
 
4380
 
 
4381
/*
 
4382
 * hold a call
 
4383
 */
 
4384
static int pbx_capi_hold(struct ast_channel *c, char *param)
 
4385
{
 
4386
        struct capi_pvt *i = CC_CHANNEL_PVT(c);
 
4387
        _cmsg   CMSG;
 
4388
        char buffer[16];
 
4389
        char    fac[4];
 
4390
 
 
4391
        /*  TODO: support holdtype notify */
 
4392
 
 
4393
        if ((i->isdnstate & CAPI_ISDN_STATE_HOLD)) {
 
4394
                cc_log(LOG_NOTICE,"%s: %s already on hold.\n",
 
4395
                        i->vname, c->name);
 
4396
                return 0;
 
4397
        }
 
4398
 
 
4399
        if (!(i->isdnstate & CAPI_ISDN_STATE_B3_UP)) {
 
4400
                cc_log(LOG_NOTICE,"%s: Cannot put on hold %s while not connected.\n",
 
4401
                        i->vname, c->name);
 
4402
                return 0;
 
4403
        }
 
4404
        if (!(capi_controllers[i->controller]->holdretrieve)) {
 
4405
                cc_log(LOG_NOTICE,"%s: HOLD for %s not supported by controller.\n",
 
4406
                        i->vname, c->name);
 
4407
                return 0;
 
4408
        }
 
4409
 
 
4410
        fac[0] = 3;     /* len */
 
4411
        fac[1] = 0x02;  /* this is a HOLD up */
 
4412
        fac[2] = 0x00;
 
4413
        fac[3] = 0;     
 
4414
 
 
4415
        FACILITY_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(),0);
 
4416
        FACILITY_REQ_PLCI(&CMSG) = i->PLCI;
 
4417
        FACILITY_REQ_FACILITYSELECTOR(&CMSG) = FACILITYSELECTOR_SUPPLEMENTARY;
 
4418
        FACILITY_REQ_FACILITYREQUESTPARAMETER(&CMSG) = (_cstruct)&fac;
 
4419
 
 
4420
        _capi_put_cmsg(&CMSG);
 
4421
        cc_verbose(2, 1, VERBOSE_PREFIX_4 "%s: sent HOLD for PLCI=%#x\n",
 
4422
                i->vname, i->PLCI);
 
4423
 
 
4424
        i->onholdPLCI = i->PLCI;
 
4425
        i->isdnstate |= CAPI_ISDN_STATE_HOLD;
 
4426
 
 
4427
        snprintf(buffer, sizeof(buffer) - 1, "%d", i->PLCI);
 
4428
        if (param) {
 
4429
                pbx_builtin_setvar_helper(i->owner, param, buffer);
 
4430
        }
 
4431
        pbx_builtin_setvar_helper(i->owner, "_CALLERHOLDID", buffer);
 
4432
 
 
4433
        return 0;
 
4434
}
 
4435
 
 
4436
/*
 
4437
 * report malicious call
 
4438
 */
 
4439
static int pbx_capi_malicious(struct ast_channel *c, char *param)
 
4440
{
 
4441
        struct capi_pvt *i = CC_CHANNEL_PVT(c);
 
4442
        _cmsg   CMSG;
 
4443
        char    fac[4];
 
4444
 
 
4445
        if (!(capi_controllers[i->controller]->MCID)) {
 
4446
                cc_log(LOG_NOTICE, "%s: MCID for %s not supported by controller.\n",
 
4447
                        i->vname, c->name);
 
4448
                return -1;
 
4449
        }
 
4450
 
 
4451
        fac[0] = 3;      /* len */
 
4452
        fac[1] = 0x0e;   /* MCID */
 
4453
        fac[2] = 0x00;
 
4454
        fac[3] = 0;     
 
4455
 
 
4456
        FACILITY_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(),0);
 
4457
        FACILITY_REQ_PLCI(&CMSG) = i->PLCI;
 
4458
        FACILITY_REQ_FACILITYSELECTOR(&CMSG) = FACILITYSELECTOR_SUPPLEMENTARY;
 
4459
        FACILITY_REQ_FACILITYREQUESTPARAMETER(&CMSG) = (_cstruct)&fac;
 
4460
 
 
4461
        cc_mutex_lock(&i->lock);
 
4462
        _capi_put_cmsg_wait_conf(i, &CMSG);
 
4463
        cc_mutex_unlock(&i->lock);
 
4464
 
 
4465
        cc_verbose(2, 1, VERBOSE_PREFIX_4 "%s: sent MCID for PLCI=%#x\n",
 
4466
                i->vname, i->PLCI);
 
4467
 
 
4468
        return 0;
 
4469
}
 
4470
 
 
4471
/*
 
4472
 * set echo cancel
 
4473
 */
 
4474
static int pbx_capi_echocancel(struct ast_channel *c, char *param)
 
4475
{
 
4476
        struct capi_pvt *i = CC_CHANNEL_PVT(c);
 
4477
 
 
4478
        if (!param) {
 
4479
                cc_log(LOG_WARNING, "Parameter for echocancel missing.\n");
 
4480
                return -1;
 
4481
        }
 
4482
        if (ast_true(param)) {
 
4483
                i->doEC = 1;
 
4484
                capi_echo_canceller(c, EC_FUNCTION_ENABLE);
 
4485
        } else if (ast_false(param)) {
 
4486
                capi_echo_canceller(c, EC_FUNCTION_DISABLE);
 
4487
                i->doEC = 0;
 
4488
        } else {
 
4489
                cc_log(LOG_WARNING, "Parameter for echocancel invalid.\n");
 
4490
                return -1;
 
4491
        }
 
4492
        cc_verbose(2, 0, VERBOSE_PREFIX_4 "%s: echocancel switched %s\n",
 
4493
                i->vname, i->doEC ? "ON":"OFF");
 
4494
        return 0;
 
4495
}
 
4496
 
 
4497
/*
 
4498
 * set echo squelch
 
4499
 */
 
4500
static int pbx_capi_echosquelch(struct ast_channel *c, char *param)
 
4501
{
 
4502
        struct capi_pvt *i = CC_CHANNEL_PVT(c);
 
4503
 
 
4504
        if (!param) {
 
4505
                cc_log(LOG_WARNING, "Parameter for echosquelch missing.\n");
 
4506
                return -1;
 
4507
        }
 
4508
        if (ast_true(param)) {
 
4509
                i->doES = 1;
 
4510
        } else if (ast_false(param)) {
 
4511
                i->doES = 0;
 
4512
        } else {
 
4513
                cc_log(LOG_WARNING, "Parameter for echosquelch invalid.\n");
 
4514
                return -1;
 
4515
        }
 
4516
        cc_verbose(2, 0, VERBOSE_PREFIX_4 "%s: echosquelch switched %s\n",
 
4517
                i->vname, i->doES ? "ON":"OFF");
 
4518
        return 0;
 
4519
}
 
4520
 
 
4521
/*
 
4522
 * set holdtype
 
4523
 */
 
4524
static int pbx_capi_holdtype(struct ast_channel *c, char *param)
 
4525
{
 
4526
        struct capi_pvt *i = CC_CHANNEL_PVT(c);
 
4527
 
 
4528
        if (!param) {
 
4529
                cc_log(LOG_WARNING, "Parameter for holdtype missing.\n");
 
4530
                return -1;
 
4531
        }
 
4532
        if (!strcasecmp(param, "hold")) {
 
4533
                i->doholdtype = CC_HOLDTYPE_HOLD;
 
4534
        } else if (!strcasecmp(param, "notify")) {
 
4535
                i->doholdtype = CC_HOLDTYPE_NOTIFY;
 
4536
        } else if (!strcasecmp(param, "local")) {
 
4537
                i->doholdtype = CC_HOLDTYPE_LOCAL;
 
4538
        } else {
 
4539
                cc_log(LOG_WARNING, "Parameter for holdtype invalid.\n");
 
4540
                return -1;
 
4541
        }
 
4542
        cc_verbose(2, 0, VERBOSE_PREFIX_4 "%s: holdtype switched to %s\n",
 
4543
                i->vname, param);
 
4544
        return 0;
 
4545
}
 
4546
 
 
4547
/*
 
4548
 * set early-B3 (progress) for incoming connections
 
4549
 * (only for NT mode)
 
4550
 */
 
4551
static int pbx_capi_signal_progress(struct ast_channel *c, char *param)
 
4552
{
 
4553
        struct capi_pvt *i = CC_CHANNEL_PVT(c);
 
4554
 
 
4555
        if ((i->state != CAPI_STATE_DID) && (i->state != CAPI_STATE_INCALL)) {
 
4556
                cc_log(LOG_DEBUG, "wrong channel state to signal PROGRESS\n");
 
4557
                return 0;
 
4558
        }
 
4559
        if (!(i->ntmode)) {
 
4560
                cc_log(LOG_WARNING, "PROGRESS sending for non NT-mode not possible\n");
 
4561
                return 0;
 
4562
        }
 
4563
        if ((i->isdnstate & CAPI_ISDN_STATE_B3_UP)) {
 
4564
                cc_verbose(4, 1, VERBOSE_PREFIX_4 "%s: signal_progress in NT: B-channel already up\n",
 
4565
                        i->vname);
 
4566
                return 0;
 
4567
        }
 
4568
 
 
4569
        cc_select_b(i, NULL);
 
4570
 
 
4571
        return 0;
 
4572
}
 
4573
 
 
4574
/*
 
4575
 * struct of capi commands
 
4576
 */
 
4577
static struct capicommands_s {
 
4578
        char *cmdname;
 
4579
        int (*cmd)(struct ast_channel *, char *);
 
4580
        int capionly;
 
4581
} capicommands[] = {
 
4582
        { "progress",     pbx_capi_signal_progress, 1 },
 
4583
        { "deflect",      pbx_capi_call_deflect,    1 },
 
4584
        { "receivefax",   pbx_capi_receive_fax,     1 },
 
4585
        { "sendfax",      pbx_capi_send_fax,        1 },
 
4586
        { "echosquelch",  pbx_capi_echosquelch,     1 },
 
4587
        { "echocancel",   pbx_capi_echocancel,      1 },
 
4588
        { "malicious",    pbx_capi_malicious,       1 },
 
4589
        { "hold",         pbx_capi_hold,            1 },
 
4590
        { "holdtype",     pbx_capi_holdtype,        1 },
 
4591
        { "retrieve",     pbx_capi_retrieve,        0 },
 
4592
        { "ect",          pbx_capi_ect,             1 },
 
4593
        { NULL, NULL, 0 }
 
4594
};
 
4595
 
 
4596
/*
 
4597
 * capi command interface
 
4598
 */
 
4599
static int pbx_capicommand_exec(struct ast_channel *chan, void *data)
 
4600
{
 
4601
        int res = 0;
 
4602
        struct localuser *u;
 
4603
        char *s;
 
4604
        char *stringp;
 
4605
        char *command, *params;
 
4606
        struct capicommands_s *capicmd = &capicommands[0];
 
4607
 
 
4608
        if (!data) {
 
4609
                cc_log(LOG_WARNING, "capiCommand requires arguments\n");
 
4610
                return -1;
 
4611
        }
 
4612
 
 
4613
        LOCAL_USER_ADD(u);
 
4614
 
 
4615
        s = ast_strdupa(data);
 
4616
        stringp = s;
 
4617
        command = strsep(&stringp, "|");
 
4618
        params = stringp;
 
4619
        cc_verbose(2, 1, VERBOSE_PREFIX_3 "capiCommand: '%s' '%s'\n",
 
4620
                command, params);
 
4621
 
 
4622
        while(capicmd->cmd) {
 
4623
                if (!strcasecmp(capicmd->cmdname, command))
 
4624
                        break;
 
4625
                capicmd++;
 
4626
        }
 
4627
        if (!capicmd->cmd) {
 
4628
                LOCAL_USER_REMOVE(u);
 
4629
                cc_log(LOG_WARNING, "Unknown command '%s' for capiCommand\n",
 
4630
                        command);
 
4631
                return -1;
 
4632
        }
 
4633
 
 
4634
        if ((capicmd->capionly) && (chan->tech->type != channeltype)) {
 
4635
                LOCAL_USER_REMOVE(u);
 
4636
                cc_log(LOG_WARNING, "capiCommand works on CAPI channels only, check your extensions.conf!\n");
 
4637
                return -1;
 
4638
        }
 
4639
 
 
4640
        res = (capicmd->cmd)(chan, params);
 
4641
        
 
4642
        LOCAL_USER_REMOVE(u);
 
4643
        return(res);
 
4644
}
 
4645
 
 
4646
/*
 
4647
 * we don't support own indications
 
4648
 */
 
4649
#ifdef CC_AST_HAS_INDICATE_DATA
 
4650
static int pbx_capi_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen)
 
4651
#else
 
4652
static int pbx_capi_indicate(struct ast_channel *c, int condition)
 
4653
#endif
 
4654
{
 
4655
        struct capi_pvt *i = CC_CHANNEL_PVT(c);
 
4656
        _cmsg CMSG;
 
4657
        int ret = -1;
 
4658
 
 
4659
        if (i == NULL) {
 
4660
                return -1;
 
4661
        }
 
4662
 
 
4663
        cc_mutex_lock(&i->lock);
 
4664
 
 
4665
        switch (condition) {
 
4666
        case AST_CONTROL_RINGING:
 
4667
                cc_verbose(3, 1, VERBOSE_PREFIX_2 "%s: Requested RINGING-Indication for %s\n",
 
4668
                        i->vname, c->name);
 
4669
                /* TODO somehow enable unhold on ringing, but when wanted only */
 
4670
                /* 
 
4671
                if (i->isdnstate & CAPI_ISDN_STATE_HOLD)
 
4672
                        pbx_capi_retrieve(c, NULL);
 
4673
                */
 
4674
                if (i->ntmode) {
 
4675
                        if ((i->isdnstate & CAPI_ISDN_STATE_B3_UP)) {
 
4676
                                ret = 0;
 
4677
                        }
 
4678
                        pbx_capi_signal_progress(c, NULL);
 
4679
                        pbx_capi_alert(c);
 
4680
                } else {
 
4681
                        ret = pbx_capi_alert(c);
 
4682
                }
 
4683
                break;
 
4684
        case AST_CONTROL_BUSY:
 
4685
                cc_verbose(3, 1, VERBOSE_PREFIX_2 "%s: Requested BUSY-Indication for %s\n",
 
4686
                        i->vname, c->name);
 
4687
                if ((i->state == CAPI_STATE_ALERTING) ||
 
4688
                    (i->state == CAPI_STATE_DID) || (i->state == CAPI_STATE_INCALL)) {
 
4689
                        CONNECT_RESP_HEADER(&CMSG, capi_ApplID, i->MessageNumber, 0);
 
4690
                        CONNECT_RESP_PLCI(&CMSG) = i->PLCI;
 
4691
                        CONNECT_RESP_REJECT(&CMSG) = 3;
 
4692
                        _capi_put_cmsg(&CMSG);
 
4693
                        ret = 0;
 
4694
                }
 
4695
                if ((i->isdnstate & CAPI_ISDN_STATE_HOLD))
 
4696
                        pbx_capi_retrieve(c, NULL);
 
4697
                break;
 
4698
        case AST_CONTROL_CONGESTION:
 
4699
                cc_verbose(3, 1, VERBOSE_PREFIX_2 "%s: Requested CONGESTION-Indication for %s\n",
 
4700
                        i->vname, c->name);
 
4701
                if ((i->state == CAPI_STATE_ALERTING) ||
 
4702
                    (i->state == CAPI_STATE_DID) || (i->state == CAPI_STATE_INCALL)) {
 
4703
                        CONNECT_RESP_HEADER(&CMSG, capi_ApplID, i->MessageNumber, 0);
 
4704
                        CONNECT_RESP_PLCI(&CMSG) = i->PLCI;
 
4705
                        CONNECT_RESP_REJECT(&CMSG) = 4;
 
4706
                        _capi_put_cmsg(&CMSG);
 
4707
                        ret = 0;
 
4708
                }
 
4709
                if ((i->isdnstate & CAPI_ISDN_STATE_HOLD))
 
4710
                        pbx_capi_retrieve(c, NULL);
 
4711
                break;
 
4712
        case AST_CONTROL_PROGRESS:
 
4713
                cc_verbose(3, 1, VERBOSE_PREFIX_2 "%s: Requested PROGRESS-Indication for %s\n",
 
4714
                        i->vname, c->name);
 
4715
                if (i->ntmode) pbx_capi_signal_progress(c, NULL);
 
4716
                break;
 
4717
        case AST_CONTROL_PROCEEDING:
 
4718
                cc_verbose(3, 1, VERBOSE_PREFIX_2 "%s: Requested PROCEEDING-Indication for %s\n",
 
4719
                        i->vname, c->name);
 
4720
                if (i->ntmode) pbx_capi_signal_progress(c, NULL);
 
4721
                break;
 
4722
        case AST_CONTROL_HOLD:
 
4723
                cc_verbose(3, 1, VERBOSE_PREFIX_2 "%s: Requested HOLD-Indication for %s\n",
 
4724
                        i->vname, c->name);
 
4725
                if (i->doholdtype != CC_HOLDTYPE_LOCAL) {
 
4726
                        ret = pbx_capi_hold(c, NULL);
 
4727
                }
 
4728
                break;
 
4729
        case AST_CONTROL_UNHOLD:
 
4730
                cc_verbose(3, 1, VERBOSE_PREFIX_2 "%s: Requested UNHOLD-Indication for %s\n",
 
4731
                        i->vname, c->name);
 
4732
                if (i->doholdtype != CC_HOLDTYPE_LOCAL) {
 
4733
                        ret = pbx_capi_retrieve(c, NULL);
 
4734
                }
 
4735
                break;
 
4736
        case -1: /* stop indications */
 
4737
                cc_verbose(3, 1, VERBOSE_PREFIX_2 "%s: Requested Indication-STOP for %s\n",
 
4738
                        i->vname, c->name);
 
4739
                if ((i->isdnstate & CAPI_ISDN_STATE_HOLD))
 
4740
                        pbx_capi_retrieve(c, NULL);
 
4741
                break;
 
4742
        default:
 
4743
                cc_verbose(3, 1, VERBOSE_PREFIX_2 "%s: Requested unknown Indication %d for %s\n",
 
4744
                        i->vname, condition, c->name);
 
4745
                break;
 
4746
        }
 
4747
        cc_mutex_unlock(&i->lock);
 
4748
        return(ret);
 
4749
}
 
4750
 
 
4751
/*
 
4752
 * PBX wants to know the state for a specific device
 
4753
 */
 
4754
static int pbx_capi_devicestate(void *data)
 
4755
{
 
4756
        int res = AST_DEVICE_UNKNOWN;
 
4757
 
 
4758
        if (!data) {
 
4759
                cc_verbose(3, 1, VERBOSE_PREFIX_2 "No data for capi_devicestate\n");
 
4760
                return res;
 
4761
        }
 
4762
 
 
4763
        cc_verbose(3, 1, VERBOSE_PREFIX_4 "CAPI devicestate requested for %s\n",
 
4764
                (char *)data);
 
4765
 
 
4766
        return res;
 
4767
}
 
4768
 
 
4769
static void capi_do_channel_task(void)
 
4770
{
 
4771
        if (chan_for_task == NULL)
 
4772
                return;
 
4773
 
 
4774
        switch(channel_task) {
 
4775
        case CAPI_CHANNEL_TASK_HANGUP:
 
4776
                /* deferred (out of lock) hangup */
 
4777
                ast_hangup(chan_for_task);
 
4778
                break;
 
4779
        case CAPI_CHANNEL_TASK_SOFTHANGUP:
 
4780
                /* deferred (out of lock) soft-hangup */
 
4781
                ast_softhangup(chan_for_task, AST_SOFTHANGUP_DEV);
 
4782
                break;
 
4783
        case CAPI_CHANNEL_TASK_PICKUP:
 
4784
                if (ast_pickup_call(chan_for_task)) {
 
4785
                        cc_verbose(3, 1, VERBOSE_PREFIX_2 "%s: Pickup not possible.\n",
 
4786
                                chan_for_task->name);
 
4787
                }
 
4788
                ast_hangup(chan_for_task);
 
4789
                break;
 
4790
        default:
 
4791
                /* nothing to do */
 
4792
                break;
 
4793
        }
 
4794
        chan_for_task = NULL;
 
4795
        channel_task = CAPI_CHANNEL_TASK_NONE;
 
4796
}
 
4797
 
 
4798
/*
 
4799
 * module stuff, monitor...
 
4800
 */
 
4801
static void *capidev_loop(void *data)
 
4802
{
 
4803
        unsigned int Info;
 
4804
        _cmsg monCMSG;
 
4805
        
 
4806
        for (/* for ever */;;) {
 
4807
                switch(Info = capidev_check_wait_get_cmsg(&monCMSG)) {
 
4808
                case 0x0000:
 
4809
                        capidev_handle_msg(&monCMSG);
 
4810
                        capi_do_channel_task();
 
4811
                        break;
 
4812
                case 0x1104:
 
4813
                        /* CAPI queue is empty */
 
4814
                        break;
 
4815
                case 0x1101:
 
4816
                        /* The application ID is no longer valid.
 
4817
                         * This error is fatal, and "chan_capi" 
 
4818
                         * should restart.
 
4819
                         */
 
4820
                        cc_log(LOG_ERROR, "CAPI reports application ID no longer valid, PANIC\n");
 
4821
                        return NULL;
 
4822
                default:
 
4823
                        /* something is wrong! */
 
4824
                        break;
 
4825
                } /* switch */
 
4826
        } /* for */
 
4827
        
 
4828
        /* never reached */
 
4829
        return NULL;
 
4830
}
 
4831
 
 
4832
/*
 
4833
 * GAIN
 
4834
 */
 
4835
static void capi_gains(struct cc_capi_gains *g, float rxgain, float txgain)
 
4836
{
 
4837
        int i = 0;
 
4838
        int x = 0;
 
4839
        
 
4840
        if (rxgain != 1.0) {
 
4841
                for (i = 0; i < 256; i++) {
 
4842
                        if (capi_capability == AST_FORMAT_ULAW) {
 
4843
                                x = (int)(((float)capiULAW2INT[i]) * rxgain);
 
4844
                        } else {
 
4845
                                x = (int)(((float)capiALAW2INT[i]) * rxgain);
 
4846
                        }
 
4847
                        if (x > 32767)
 
4848
                                x = 32767;
 
4849
                        if (x < -32767)
 
4850
                                x = -32767;
 
4851
                        if (capi_capability == AST_FORMAT_ULAW) {
 
4852
                                g->rxgains[i] = capi_int2ulaw(x);
 
4853
                        } else {
 
4854
                                g->rxgains[i] = capi_int2alaw(x);
 
4855
                        }
 
4856
                }
 
4857
        }
 
4858
        
 
4859
        if (txgain != 1.0) {
 
4860
                for (i = 0; i < 256; i++) {
 
4861
                        if (capi_capability == AST_FORMAT_ULAW) {
 
4862
                                x = (int)(((float)capiULAW2INT[i]) * txgain);
 
4863
                        } else {
 
4864
                                x = (int)(((float)capiALAW2INT[i]) * txgain);
 
4865
                        }
 
4866
                        if (x > 32767)
 
4867
                                x = 32767;
 
4868
                        if (x < -32767)
 
4869
                                x = -32767;
 
4870
                        if (capi_capability == AST_FORMAT_ULAW) {
 
4871
                                g->txgains[i] = capi_int2ulaw(x);
 
4872
                        } else {
 
4873
                                g->txgains[i] = capi_int2alaw(x);
 
4874
                        }
 
4875
                }
 
4876
        }
 
4877
}
 
4878
 
 
4879
/*
 
4880
 * create new interface
 
4881
 */
 
4882
int mkif(struct cc_capi_conf *conf)
 
4883
{
 
4884
        struct capi_pvt *tmp;
 
4885
        int i = 0;
 
4886
        u_int16_t unit;
 
4887
 
 
4888
        for (i = 0; i <= conf->devices; i++) {
 
4889
                tmp = malloc(sizeof(struct capi_pvt));
 
4890
                if (!tmp) {
 
4891
                        return -1;
 
4892
                }
 
4893
                memset(tmp, 0, sizeof(struct capi_pvt));
 
4894
        
 
4895
                tmp->readerfd = -1;
 
4896
                tmp->writerfd = -1;
 
4897
                
 
4898
                cc_mutex_init(&tmp->lock);
 
4899
                ast_cond_init(&tmp->event_trigger, NULL);
 
4900
        
 
4901
                if (i == 0) {
 
4902
                        snprintf(tmp->name, sizeof(tmp->name) - 1, "%s-pseudo-D", conf->name);
 
4903
                        tmp->channeltype = CAPI_CHANNELTYPE_D;
 
4904
                } else {
 
4905
                        cc_copy_string(tmp->name, conf->name, sizeof(tmp->name));
 
4906
                        tmp->channeltype = CAPI_CHANNELTYPE_B;
 
4907
                }
 
4908
                snprintf(tmp->vname, sizeof(tmp->vname) - 1, "%s#%02d", conf->name, i);
 
4909
                cc_copy_string(tmp->context, conf->context, sizeof(tmp->context));
 
4910
                cc_copy_string(tmp->incomingmsn, conf->incomingmsn, sizeof(tmp->incomingmsn));
 
4911
                cc_copy_string(tmp->defaultcid, conf->defaultcid, sizeof(tmp->defaultcid));
 
4912
                cc_copy_string(tmp->prefix, conf->prefix, sizeof(tmp->prefix));
 
4913
                cc_copy_string(tmp->accountcode, conf->accountcode, sizeof(tmp->accountcode));
 
4914
                cc_copy_string(tmp->language, conf->language, sizeof(tmp->language));
 
4915
 
 
4916
                unit = atoi(conf->controllerstr);
 
4917
                        /* There is no reason not to
 
4918
                         * allow controller 0 !
 
4919
                         *
 
4920
                         * Hide problem from user:
 
4921
                         */
 
4922
                        if (unit == 0) {
 
4923
                                /* The ISDN4BSD kernel will modulo
 
4924
                                 * the controller number by 
 
4925
                                 * "capi_num_controllers", so this
 
4926
                                 * is equivalent to "0":
 
4927
                                 */
 
4928
                                unit = capi_num_controllers;
 
4929
                        }
 
4930
 
 
4931
                /* always range check user input */
 
4932
                if (unit > CAPI_MAX_CONTROLLERS)
 
4933
                        unit = CAPI_MAX_CONTROLLERS;
 
4934
 
 
4935
                tmp->controller = unit;
 
4936
                capi_used_controllers |= (1 << unit);
 
4937
                tmp->doEC = conf->echocancel;
 
4938
                tmp->ecOption = conf->ecoption;
 
4939
                if (conf->ecnlp) tmp->ecOption |= 0x01; /* bit 0 of ec-option is NLP */
 
4940
                tmp->ecTail = conf->ectail;
 
4941
                tmp->isdnmode = conf->isdnmode;
 
4942
                tmp->ntmode = conf->ntmode;
 
4943
                tmp->ES = conf->es;
 
4944
                tmp->callgroup = conf->callgroup;
 
4945
                tmp->pickupgroup = conf->pickupgroup;
 
4946
                tmp->group = conf->group;
 
4947
                tmp->amaflags = conf->amaflags;
 
4948
                tmp->immediate = conf->immediate;
 
4949
                tmp->holdtype = conf->holdtype;
 
4950
                tmp->ecSelector = conf->ecSelector;
 
4951
                tmp->bridge = conf->bridge;
 
4952
                tmp->FaxState = conf->faxsetting;
 
4953
                
 
4954
                tmp->smoother = ast_smoother_new(CAPI_MAX_B3_BLOCK_SIZE);
 
4955
 
 
4956
                tmp->rxgain = conf->rxgain;
 
4957
                tmp->txgain = conf->txgain;
 
4958
                capi_gains(&tmp->g, conf->rxgain, conf->txgain);
 
4959
 
 
4960
                tmp->doDTMF = conf->softdtmf;
 
4961
                tmp->capability = conf->capability;
 
4962
 
 
4963
                tmp->next = iflist; /* prepend */
 
4964
                iflist = tmp;
 
4965
                cc_verbose(2, 0, VERBOSE_PREFIX_3 "capi %c %s (%s:%s) contr=%d devs=%d EC=%d,opt=%d,tail=%d\n",
 
4966
                        (tmp->channeltype == CAPI_CHANNELTYPE_B)? 'B' : 'D',
 
4967
                        tmp->vname, tmp->incomingmsn, tmp->context, tmp->controller,
 
4968
                        conf->devices, tmp->doEC, tmp->ecOption, tmp->ecTail);
 
4969
        }
 
4970
        return 0;
 
4971
}
 
4972
 
 
4973
/*
 
4974
 * eval supported services
 
4975
 */
 
4976
static void supported_sservices(struct cc_capi_controller *cp)
 
4977
{
 
4978
        MESSAGE_EXCHANGE_ERROR error;
 
4979
        _cmsg CMSG, CMSG2;
 
4980
        struct timeval tv;
 
4981
        unsigned char fac[20];
 
4982
        unsigned int services;
 
4983
 
 
4984
        memset(fac, 0, sizeof(fac));
 
4985
        FACILITY_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(), 0);
 
4986
        FACILITY_REQ_CONTROLLER(&CMSG) = cp->controller;
 
4987
        FACILITY_REQ_FACILITYSELECTOR(&CMSG) = FACILITYSELECTOR_SUPPLEMENTARY;
 
4988
        fac[0] = 3;
 
4989
        FACILITY_REQ_FACILITYREQUESTPARAMETER(&CMSG) = (_cstruct)&fac;
 
4990
        _capi_put_cmsg(&CMSG);
 
4991
 
 
4992
        tv.tv_sec = 1;
 
4993
        tv.tv_usec = 0;
 
4994
        
 
4995
        for (/* for ever */;;) {
 
4996
                error = capi20_waitformessage(capi_ApplID, &tv);
 
4997
                error = capi_get_cmsg(&CMSG2, capi_ApplID); 
 
4998
                if (error == 0) {
 
4999
                        if (IS_FACILITY_CONF(&CMSG2)) {
 
5000
                                cc_verbose(5, 0, VERBOSE_PREFIX_4 "FACILITY_CONF INFO = %#x\n",
 
5001
                                        FACILITY_CONF_INFO(&CMSG2));
 
5002
                                break;
 
5003
                        }
 
5004
                }
 
5005
        } 
 
5006
 
 
5007
        /* parse supported sservices */
 
5008
        if (FACILITY_CONF_FACILITYSELECTOR(&CMSG2) != FACILITYSELECTOR_SUPPLEMENTARY) {
 
5009
                cc_log(LOG_NOTICE, "unexpected FACILITY_SELECTOR = %#x\n",
 
5010
                        FACILITY_CONF_FACILITYSELECTOR(&CMSG2));
 
5011
                return;
 
5012
        }
 
5013
 
 
5014
        if (FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[4] != 0) {
 
5015
                cc_log(LOG_NOTICE, "supplementary services info  = %#x\n",
 
5016
                        (short)FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[1]);
 
5017
                return;
 
5018
        }
 
5019
        services = read_capi_dword(&(FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[6]));
 
5020
        cc_verbose(3, 0, VERBOSE_PREFIX_4 "supplementary services : 0x%08x\n",
 
5021
                services);
 
5022
        
 
5023
        /* success, so set the features we have */
 
5024
        cc_verbose(3, 0, VERBOSE_PREFIX_4 " ");
 
5025
        if (services & 0x0001) {
2437
5026
                cp->holdretrieve = 1;
2438
 
                if (option_verbose > 3)
2439
 
                    ast_verbose(VERBOSE_PREFIX_4 "HOLD/RETRIEVE\n");
2440
 
            } else {
2441
 
                cp->holdretrieve = 0;   
2442
 
            }
2443
 
            if (((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[6] & 2) >> 1) == 1) {
 
5027
                cc_verbose(3, 0, "HOLD/RETRIEVE ");
 
5028
        }
 
5029
        if (services & 0x0002) {
2444
5030
                cp->terminalportability = 1;
2445
 
                if (option_verbose > 3)
2446
 
                    ast_verbose(VERBOSE_PREFIX_4 "TERMINAL PORTABILITY\n");
2447
 
            } else {
2448
 
                cp->terminalportability = 0;
2449
 
            }
2450
 
            if (((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[6] & 4) >> 2) == 1) {
 
5031
                cc_verbose(3, 0, "TERMINAL-PORTABILITY ");
 
5032
        }
 
5033
        if (services & 0x0004) {
2451
5034
                cp->ECT = 1;
2452
 
                if (option_verbose > 3)
2453
 
                    ast_verbose(VERBOSE_PREFIX_4 "ECT\n");
2454
 
            } else {
2455
 
                cp->ECT = 0;
2456
 
            }
2457
 
            if (((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[6] & 8) >> 3) == 1) {
 
5035
                cc_verbose(3, 0, "ECT ");
 
5036
        }
 
5037
        if (services & 0x0008) {
2458
5038
                cp->threePTY = 1;
2459
 
                if (option_verbose > 3)
2460
 
                    ast_verbose(VERBOSE_PREFIX_4 "3PTY\n");
2461
 
            } else {
2462
 
                cp->threePTY = 0;
2463
 
            }
2464
 
            if (((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[6] & 16) >> 4) == 1) {
 
5039
                cc_verbose(3, 0, "3PTY ");
 
5040
        }
 
5041
        if (services & 0x0010) {
2465
5042
                cp->CF = 1;
2466
 
                if (option_verbose > 3)
2467
 
                    ast_verbose(VERBOSE_PREFIX_4 "CF\n");
2468
 
            } else {
2469
 
                cp->CF = 0;
2470
 
            }
2471
 
            if (((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[6] & 32) >> 5) == 1) {
 
5043
                cc_verbose(3, 0, "CF ");
 
5044
        }
 
5045
        if (services & 0x0020) {
2472
5046
                cp->CD = 1;
2473
 
                if (option_verbose > 3)
2474
 
                    ast_verbose(VERBOSE_PREFIX_4 "CD\n");
2475
 
            } else {
2476
 
                cp->CD = 0;
2477
 
            }
2478
 
            if (((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[6] & 64) >> 6) == 1) {
 
5047
                cc_verbose(3, 0, "CD ");
 
5048
        }
 
5049
        if (services & 0x0040) {
2479
5050
                cp->MCID = 1;
2480
 
                if (option_verbose > 3)
2481
 
                    ast_verbose(VERBOSE_PREFIX_4 "MCID\n");
2482
 
            } else {
2483
 
                cp->MCID = 0;
2484
 
            }
2485
 
            if (((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[6] & 128) >> 7) == 1) {
 
5051
                cc_verbose(3, 0, "MCID ");
 
5052
        }
 
5053
        if (services & 0x0080) {
2486
5054
                cp->CCBS = 1;
2487
 
                if (option_verbose > 3)
2488
 
                    ast_verbose(VERBOSE_PREFIX_4 "CCBS\n");
2489
 
            } else {
2490
 
                cp->CCBS = 0;
2491
 
            }
2492
 
            if ((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[7] & 1) == 1) {
 
5055
                cc_verbose(3, 0, "CCBS ");
 
5056
        }
 
5057
        if (services & 0x0100) {
2493
5058
                cp->MWI = 1;
2494
 
                if (option_verbose > 3)
2495
 
                    ast_verbose(VERBOSE_PREFIX_4 "MWI\n");
2496
 
            } else {
2497
 
                cp->MWI = 0;
2498
 
            }
2499
 
            if (((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[7] & 2) >> 1) == 1) {
 
5059
                cc_verbose(3, 0, "MWI ");
 
5060
        }
 
5061
        if (services & 0x0200) {
2500
5062
                cp->CCNR = 1;
2501
 
                if (option_verbose > 3)
2502
 
                    ast_verbose(VERBOSE_PREFIX_4 "CCNR\n");
2503
 
            } else {
2504
 
                cp->CCNR = 0;
2505
 
            }
2506
 
            if (((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[7] & 4) >> 2) == 1) {
 
5063
                cc_verbose(3, 0, "CCNR ");
 
5064
        }
 
5065
        if (services & 0x0400) {
2507
5066
                cp->CONF = 1;
2508
 
                if (option_verbose > 3)
2509
 
                    ast_verbose(VERBOSE_PREFIX_4 "CONF\n");
2510
 
            } else {
2511
 
                cp->CONF = 0;
2512
 
            }
2513
 
        } else {
2514
 
            ast_log(LOG_NOTICE,"supplementary services info  = %#x\n",(short)FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[1]);
2515
 
        }
2516
 
    } else  {
2517
 
        ast_log(LOG_NOTICE,"unexpected FACILITY_SELECTOR = %#x\n",FACILITY_CONF_FACILITYSELECTOR(&CMSG2));
2518
 
    }
2519
 
}
2520
 
 
2521
 
static int capi_info(int fd, int argc, char *argv[])
2522
 
{
2523
 
        int i=0;
2524
 
        if (argc != 2)
2525
 
                return RESULT_SHOWUSAGE;
2526
 
        for (i=1;i<=capi_num_controllers;i++) {
2527
 
            ast_mutex_lock(&contrlock);
2528
 
            if (capi_controllers[i] != NULL) {
2529
 
                ast_cli(fd,"Contr%d: %d B channels total, %d B channels free.\n",i,capi_controllers[i]->nbchannels,capi_controllers[i]->nfreebchannels);
2530
 
            }
2531
 
            ast_mutex_unlock(&contrlock);
2532
 
        }
2533
 
        return RESULT_SUCCESS;
2534
 
}
2535
 
 
2536
 
static int capi_do_debug(int fd, int argc, char *argv[])
2537
 
{
2538
 
        if (argc != 2)
2539
 
                return RESULT_SHOWUSAGE;
 
5067
                cc_verbose(3, 0, "CONF");
 
5068
        }
 
5069
        cc_verbose(3, 0, "\n");
 
5070
        return;
 
5071
}
 
5072
 
 
5073
/*
 
5074
 * helper functions to convert conf value to string
 
5075
 */
 
5076
static char *show_bproto(int bproto)
 
5077
{
 
5078
        switch(bproto) {
 
5079
        case CC_BPROTO_TRANSPARENT:
 
5080
                return "trans";
 
5081
        case CC_BPROTO_FAXG3:
 
5082
                return " fax ";
 
5083
        case CC_BPROTO_RTP:
 
5084
                return " rtp ";
 
5085
        }
 
5086
        return " ??? ";
 
5087
}
 
5088
static char *show_state(int state)
 
5089
{
 
5090
        switch(state) {
 
5091
        case CAPI_STATE_ALERTING:
 
5092
                return "Ring ";
 
5093
        case CAPI_STATE_CONNECTED:
 
5094
                return "Conn ";
 
5095
        case CAPI_STATE_DISCONNECTING:
 
5096
                return "discP";
 
5097
        case CAPI_STATE_DISCONNECTED:
 
5098
                return "Disc ";
 
5099
        case CAPI_STATE_CONNECTPENDING:
 
5100
                return "Dial ";
 
5101
        case CAPI_STATE_ANSWERING:
 
5102
                return "Answ ";
 
5103
        case CAPI_STATE_DID:
 
5104
                return "DIDin";
 
5105
        case CAPI_STATE_INCALL:
 
5106
                return "icall";
 
5107
        case CAPI_STATE_ONHOLD:
 
5108
                return "Hold ";
 
5109
        }
 
5110
        return "-----";
 
5111
}
 
5112
static char *show_isdnstate(unsigned int isdnstate, char *str)
 
5113
{
 
5114
        str[0] = '\0';
 
5115
 
 
5116
        if (isdnstate & CAPI_ISDN_STATE_PBX)
 
5117
                strcat(str, "*");
 
5118
        if (isdnstate & CAPI_ISDN_STATE_LI)
 
5119
                strcat(str, "G");
 
5120
        if (isdnstate & CAPI_ISDN_STATE_B3_UP)
 
5121
                strcat(str, "B");
 
5122
        if (isdnstate & CAPI_ISDN_STATE_B3_PEND)
 
5123
                strcat(str, "b");
 
5124
        if (isdnstate & CAPI_ISDN_STATE_PROGRESS)
 
5125
                strcat(str, "P");
 
5126
        if (isdnstate & CAPI_ISDN_STATE_HOLD)
 
5127
                strcat(str, "H");
 
5128
        if (isdnstate & CAPI_ISDN_STATE_ECT)
 
5129
                strcat(str, "T");
 
5130
        if (isdnstate & (CAPI_ISDN_STATE_SETUP | CAPI_ISDN_STATE_SETUP_ACK))
 
5131
                strcat(str, "S");
 
5132
 
 
5133
        return str;
 
5134
}
 
5135
 
 
5136
/*
 
5137
 * do command capi show channels
 
5138
 */
 
5139
static int pbxcli_capi_show_channels(int fd, int argc, char *argv[])
 
5140
{
 
5141
        struct capi_pvt *i;
 
5142
        char iochar;
 
5143
        char i_state[80];
 
5144
        char b3q[16];
 
5145
        
 
5146
        if (argc != 3)
 
5147
                return RESULT_SHOWUSAGE;
 
5148
        
 
5149
        ast_cli(fd, "CAPI B-channel information:\n");
 
5150
        ast_cli(fd, "Line-Name       NTmode state i/o bproto isdnstate   ton  number\n");
 
5151
        ast_cli(fd, "----------------------------------------------------------------\n");
 
5152
 
 
5153
        cc_mutex_lock(&iflock);
 
5154
 
 
5155
        for (i = iflist; i; i = i->next) {
 
5156
                if (i->channeltype != CAPI_CHANNELTYPE_B)
 
5157
                        continue;
 
5158
 
 
5159
                if ((i->state == 0) || (i->state == CAPI_STATE_DISCONNECTED))
 
5160
                        iochar = '-';
 
5161
                else if (i->outgoing)
 
5162
                        iochar = 'O';
 
5163
                else
 
5164
                        iochar = 'I';
 
5165
 
 
5166
                if (capidebug)
 
5167
                        snprintf(b3q, sizeof(b3q), "  B3q=%d", i->B3q);
 
5168
                else
 
5169
                        b3q[0] = '\0';
 
5170
 
 
5171
                ast_cli(fd,
 
5172
                        "%-16s %s   %s  %c  %s  %-10s  0x%02x '%s'->'%s'%s\n",
 
5173
                        i->vname,
 
5174
                        i->ntmode ? "yes":"no ",
 
5175
                        show_state(i->state),
 
5176
                        iochar,
 
5177
                        show_bproto(i->bproto),
 
5178
                        show_isdnstate(i->isdnstate, i_state),
 
5179
                        i->cid_ton,
 
5180
                        i->cid,
 
5181
                        i->dnid,
 
5182
                        b3q
 
5183
                );
 
5184
        }
 
5185
 
 
5186
        cc_mutex_unlock(&iflock);
 
5187
                
 
5188
        return RESULT_SUCCESS;
 
5189
}
 
5190
 
 
5191
/*
 
5192
 * do command capi info
 
5193
 */
 
5194
static int pbxcli_capi_info(int fd, int argc, char *argv[])
 
5195
{
 
5196
        int i = 0;
 
5197
        
 
5198
        if (argc != 2)
 
5199
                return RESULT_SHOWUSAGE;
 
5200
                
 
5201
        for (i = 1; i <= capi_num_controllers; i++) {
 
5202
                if (capi_controllers[i] != NULL) {
 
5203
                        ast_cli(fd, "Contr%d: %d B channels total, %d B channels free.\n",
 
5204
                                i, capi_controllers[i]->nbchannels,
 
5205
                                capi_controllers[i]->nfreebchannels);
 
5206
                }
 
5207
        }
 
5208
        return RESULT_SUCCESS;
 
5209
}
 
5210
 
 
5211
/*
 
5212
 * enable debugging
 
5213
 */
 
5214
static int pbxcli_capi_do_debug(int fd, int argc, char *argv[])
 
5215
{
 
5216
        if (argc != 2)
 
5217
                return RESULT_SHOWUSAGE;
 
5218
                
2540
5219
        capidebug = 1;
2541
5220
        ast_cli(fd, "CAPI Debugging Enabled\n");
 
5221
        
2542
5222
        return RESULT_SUCCESS;
2543
5223
}
2544
5224
 
2545
 
static int capi_no_debug(int fd, int argc, char *argv[])
 
5225
/*
 
5226
 * disable debugging
 
5227
 */
 
5228
static int pbxcli_capi_no_debug(int fd, int argc, char *argv[])
2546
5229
{
2547
5230
        if (argc != 3)
2548
5231
                return RESULT_SHOWUSAGE;
 
5232
 
2549
5233
        capidebug = 0;
2550
5234
        ast_cli(fd, "CAPI Debugging Disabled\n");
 
5235
        
2551
5236
        return RESULT_SUCCESS;
2552
5237
}
2553
5238
 
 
5239
/*
 
5240
 * usages
 
5241
 */
2554
5242
static char info_usage[] = 
2555
5243
"Usage: capi info\n"
 
5244
"       Show info about B channels on controllers.\n";
 
5245
 
 
5246
static char show_channels_usage[] = 
 
5247
"Usage: capi show channels\n"
2556
5248
"       Show info about B channels.\n";
2557
5249
 
2558
5250
static char debug_usage[] = 
2563
5255
"Usage: capi no debug\n"
2564
5256
"       Disables dumping of CAPI packets for debugging purposes\n";
2565
5257
 
 
5258
/*
 
5259
 * define commands
 
5260
 */
2566
5261
static struct ast_cli_entry  cli_info =
2567
 
        { { "capi", "info", NULL }, capi_info, "Show CAPI info", info_usage };
 
5262
        { { "capi", "info", NULL }, pbxcli_capi_info, "Show CAPI info", info_usage };
 
5263
static struct ast_cli_entry  cli_show_channels =
 
5264
        { { "capi", "show", "channels", NULL }, pbxcli_capi_show_channels, "Show B-channel info", show_channels_usage };
2568
5265
static struct ast_cli_entry  cli_debug =
2569
 
        { { "capi", "debug", NULL }, capi_do_debug, "Enable CAPI debugging", debug_usage };
 
5266
        { { "capi", "debug", NULL }, pbxcli_capi_do_debug, "Enable CAPI debugging", debug_usage };
2570
5267
static struct ast_cli_entry  cli_no_debug =
2571
 
        { { "capi", "no", "debug", NULL }, capi_no_debug, "Disable CAPI debugging", no_debug_usage };
2572
 
 
2573
 
 
2574
 
int load_module(void)
2575
 
{
2576
 
        struct ast_config *cfg;
2577
 
        struct ast_variable *v;
2578
 
        char *config = "capi.conf";
2579
 
        char msn[AST_MAX_EXTENSION]="";
2580
 
        char incomingmsn[AST_MAX_EXTENSION]="";
2581
 
        char context[AST_MAX_EXTENSION]="";
2582
 
        char prefix[AST_MAX_EXTENSION]="";
2583
 
        char accountcode[20]="";
2584
 
        char *empty = "\0";
2585
 
        char deflect2[AST_MAX_EXTENSION]="";
2586
 
        char controllerstr[AST_MAX_EXTENSION]="";
2587
 
        int res = 0;
2588
 
        int controller=0;
2589
 
        int softdtmf=0;
2590
 
        int echocancel=1;
2591
 
        int ecoption=EC_OPTION_DISABLE_G165;
2592
 
        int ectail=EC_DEFAULT_TAIL;
2593
 
        int es=0;
2594
 
        float rxgain = 1.0;
2595
 
        float txgain = 1.0;
2596
 
        int isdnmode = 0;
2597
 
        unsigned int callgroup=0;
2598
 
        struct ast_capi_controller *cp;
2599
 
 
2600
 
        cfg = ast_load(config);
2601
 
 
2602
 
        /* We *must* have a config file otherwise stop immediately */
2603
 
        if (!cfg) {
2604
 
                ast_log(LOG_ERROR, "Unable to load config %s\n", config);
2605
 
                return -1;
2606
 
        }
2607
 
        if (ast_mutex_lock(&iflock)) {
2608
 
                ast_log(LOG_ERROR, "Unable to lock interface list???\n");
2609
 
                return -1;
2610
 
        }
2611
 
 
2612
 
        strncpy(capi_national_prefix, AST_CAPI_NATIONAL_PREF, sizeof(capi_national_prefix)-1);
2613
 
        strncpy(capi_international_prefix, AST_CAPI_NATIONAL_PREF, sizeof(capi_national_prefix)-1);
2614
 
        v = ast_variable_browse(cfg, "general");
2615
 
        while(v) {
2616
 
                if (!strcasecmp(v->name, "nationalprefix")) {
2617
 
                    strncpy(capi_national_prefix, v->value, sizeof(capi_national_prefix)-1);
2618
 
                } else if (!strcasecmp(v->name, "internationalprefix")) {
2619
 
                        strncpy(capi_international_prefix, v->value, sizeof(capi_international_prefix)-1);
2620
 
                } else if (!strcasecmp(v->name, "rxgain")) {
2621
 
                        if (sscanf(v->value,"%f",&rxgain) != 1) {
2622
 
                            ast_log(LOG_ERROR,"invalid rxgain\n");
2623
 
                        }
2624
 
                } else if (!strcasecmp(v->name, "txgain")) {
2625
 
                        if (sscanf(v->value,"%f",&txgain) != 1) {
2626
 
                            ast_log(LOG_ERROR,"invalid txgain\n");
2627
 
                        }
2628
 
                }
2629
 
                v = v->next;
2630
 
        }
2631
 
 
2632
 
 
2633
 
 
2634
 
        
 
5268
        { { "capi", "no", "debug", NULL }, pbxcli_capi_no_debug, "Disable CAPI debugging", no_debug_usage };
 
5269
 
 
5270
static const struct ast_channel_tech capi_tech = {
 
5271
        .type = channeltype,
 
5272
        .description = tdesc,
 
5273
        .capabilities = AST_FORMAT_ALAW,
 
5274
        .requester = pbx_capi_request,
 
5275
        .send_digit = pbx_capi_send_digit,
 
5276
        .send_text = NULL,
 
5277
        .call = pbx_capi_call,
 
5278
        .hangup = pbx_capi_hangup,
 
5279
        .answer = pbx_capi_answer,
 
5280
        .read = pbx_capi_read,
 
5281
        .write = pbx_capi_write,
 
5282
        .bridge = pbx_capi_bridge,
 
5283
        .exception = NULL,
 
5284
        .indicate = pbx_capi_indicate,
 
5285
        .fixup = pbx_capi_fixup,
 
5286
        .setoption = NULL,
 
5287
        .devicestate = pbx_capi_devicestate,
 
5288
};
 
5289
 
 
5290
/*
 
5291
 * register at CAPI interface
 
5292
 */
 
5293
static int cc_register_capi(unsigned blocksize)
 
5294
{
 
5295
        u_int16_t error = 0;
 
5296
 
 
5297
        if (capi_ApplID != CAPI_APPLID_UNUSED) {
 
5298
                if (capi20_release(capi_ApplID) != 0)
 
5299
                        cc_log(LOG_WARNING,"Unable to unregister from CAPI!\n");
 
5300
        }
 
5301
        cc_verbose(3, 0, VERBOSE_PREFIX_3 "Registering at CAPI "
 
5302
                   "(blocksize=%d)\n", blocksize);
 
5303
 
 
5304
#if (CAPI_OS_HINT == 2)
 
5305
        error = capi20_register(CAPI_BCHANS, CAPI_MAX_B3_BLOCKS, 
 
5306
                                blocksize, &capi_ApplID, CAPI_STACK_VERSION);
 
5307
#else
 
5308
        error = capi20_register(CAPI_BCHANS, CAPI_MAX_B3_BLOCKS, 
 
5309
                                blocksize, &capi_ApplID);
 
5310
#endif
 
5311
        if (error != 0) {
 
5312
                capi_ApplID = CAPI_APPLID_UNUSED;
 
5313
                cc_log(LOG_NOTICE,"unable to register application at CAPI!\n");
 
5314
                return -1;
 
5315
        }
 
5316
        return 0;
 
5317
}
 
5318
 
 
5319
/*
 
5320
 * init capi stuff
 
5321
 */
 
5322
static int cc_init_capi(void)
 
5323
{
 
5324
#if (CAPI_OS_HINT == 1)
 
5325
        CAPIProfileBuffer_t profile;
 
5326
#else
 
5327
        struct cc_capi_profile profile;
 
5328
#endif
 
5329
        struct cc_capi_controller *cp;
 
5330
        int controller;
 
5331
        unsigned int privateoptions;
 
5332
 
2635
5333
        if (capi20_isinstalled() != 0) {
2636
 
            ast_log(LOG_NOTICE,"CAPI not installed!\n");
2637
 
            return -1;
2638
 
        }
2639
 
 
2640
 
        if (capi20_register(AST_CAPI_BCHANS,AST_CAPI_MAX_B3_BLOCKS,AST_CAPI_MAX_B3_BLOCK_SIZE,&ast_capi_ApplID) != 0) {
2641
 
            ast_log(LOG_NOTICE,"unable to register application at CAPI!\n");
2642
 
            return -1;
2643
 
        }
2644
 
 
2645
 
        if (Listen(ALL_SERVICES) != 0) {
2646
 
            ast_log(LOG_NOTICE,"unable to listen!\n");
2647
 
            return -1;
2648
 
        }
2649
 
 
2650
 
        if (capi20_get_profile(0,(char *)&profile) != 0) {
2651
 
            ast_log(LOG_NOTICE,"unable to get CAPI profile!\n");
2652
 
            return -1;
2653
 
        } else {
2654
 
            capi_num_controllers = profile.ncontrollers;
2655
 
            if (option_verbose > 3)
2656
 
            ast_verbose(VERBOSE_PREFIX_3 "This box has %d capi controller(s).\n",capi_num_controllers);
2657
 
            for (controller=1;controller<=capi_num_controllers;controller++) {
2658
 
 
2659
 
                memset(&profile,0,sizeof(profile));
2660
 
                capi20_get_profile(controller,(char *)&profile);
2661
 
                cp = malloc(sizeof(struct ast_capi_controller));
 
5334
                cc_log(LOG_WARNING, "CAPI not installed, CAPI disabled!\n");
 
5335
                return -1;
 
5336
        }
 
5337
 
 
5338
        if (cc_register_capi(CAPI_MAX_B3_BLOCK_SIZE))
 
5339
                return -1;
 
5340
 
 
5341
#if (CAPI_OS_HINT == 1)
 
5342
        if (capi20_get_profile(0, &profile) != 0) {
 
5343
#elif (CAPI_OS_HINT == 2)
 
5344
        if (capi20_get_profile(0, &profile, sizeof(profile)) != 0) {
 
5345
#else
 
5346
        if (capi20_get_profile(0, (unsigned char *)&profile) != 0) {
 
5347
#endif
 
5348
                cc_log(LOG_NOTICE,"unable to get CAPI profile!\n");
 
5349
                return -1;
 
5350
        } 
 
5351
 
 
5352
#if (CAPI_OS_HINT == 1)
 
5353
        capi_num_controllers = profile.wCtlr;
 
5354
#else
 
5355
        capi_num_controllers = profile.ncontrollers;
 
5356
#endif
 
5357
 
 
5358
        cc_verbose(3, 0, VERBOSE_PREFIX_2 "This box has %d capi controller(s).\n",
 
5359
                capi_num_controllers);
 
5360
        
 
5361
        for (controller = 1 ;controller <= capi_num_controllers; controller++) {
 
5362
 
 
5363
                memset(&profile, 0, sizeof(profile));
 
5364
#if (CAPI_OS_HINT == 1)
 
5365
                capi20_get_profile(controller, &profile);
 
5366
#elif (CAPI_OS_HINT == 2)
 
5367
                capi20_get_profile(controller, &profile, sizeof(profile));
 
5368
#else
 
5369
                capi20_get_profile(controller, (unsigned char *)&profile);
 
5370
#endif
 
5371
                cp = malloc(sizeof(struct cc_capi_controller));
 
5372
                if (!cp) {
 
5373
                        cc_log(LOG_ERROR, "Error allocating memory for struct cc_capi_controller\n");
 
5374
                        return -1;
 
5375
                }
 
5376
                memset(cp, 0, sizeof(struct cc_capi_controller));
2662
5377
                cp->controller = controller;
 
5378
#if (CAPI_OS_HINT == 1)
 
5379
                cp->nbchannels = profile.wNumBChannels;
 
5380
                cp->nfreebchannels = profile.wNumBChannels;
 
5381
                if (profile.dwGlobalOptions & CAPI_PROFILE_DTMF_SUPPORT) {
 
5382
#else
2663
5383
                cp->nbchannels = profile.nbchannels;
2664
5384
                cp->nfreebchannels = profile.nbchannels;
2665
 
                if ((profile.globaloptions & 8) >> 3 == 1) {
2666
 
                    if (option_verbose > 3)
2667
 
                        ast_verbose(VERBOSE_PREFIX_3 "CAPI[contr%d] supports DTMF\n",controller);
2668
 
                    cp->dtmf = 1;
2669
 
                } else {
2670
 
                    cp->dtmf = 0;           
2671
 
                }
2672
 
                if (profile.globaloptions2 & 1) {
2673
 
                    if (option_verbose > 3)
2674
 
                        ast_verbose(VERBOSE_PREFIX_3 "CAPI[contr%d] supports echo cancellation\n",controller);
2675
 
                    cp->echocancel = 1;
2676
 
                } else {
2677
 
                    cp->echocancel = 0;
2678
 
                }
2679
 
                if ((profile.globaloptions & 16) >> 4 == 1) {
2680
 
                    cp->sservices = 1;
2681
 
                } else {
2682
 
                    cp->sservices = 0;      
2683
 
                }
 
5385
                if (profile.globaloptions & 0x08) {
 
5386
#endif
 
5387
                        cc_verbose(3, 0, VERBOSE_PREFIX_3 "CAPI/contr%d supports DTMF\n",
 
5388
                                controller);
 
5389
                        cp->dtmf = 1;
 
5390
                }
 
5391
                
 
5392
#if (CAPI_OS_HINT == 1)
 
5393
                if (profile.dwGlobalOptions & CAPI_PROFILE_ECHO_CANCELLATION) {
 
5394
#else
 
5395
                if (profile.globaloptions2 & 0x02) {
 
5396
#endif
 
5397
                        cc_verbose(3, 0, VERBOSE_PREFIX_3 "CAPI/contr%d supports echo cancellation\n",
 
5398
                                controller);
 
5399
                        cp->echocancel = 1;
 
5400
                }
 
5401
                
 
5402
#if (CAPI_OS_HINT == 1)
 
5403
                if (profile.dwGlobalOptions & CAPI_PROFILE_SUPPLEMENTARY_SERVICES)  {
 
5404
#else
 
5405
                if (profile.globaloptions & 0x10) {
 
5406
#endif
 
5407
                        cp->sservices = 1;
 
5408
                }
 
5409
 
 
5410
#if (CAPI_OS_HINT == 1)
 
5411
                if (profile.dwGlobalOptions & 0x80)  {
 
5412
#else
 
5413
                if (profile.globaloptions & 0x80) {
 
5414
#endif
 
5415
                        cc_verbose(3, 0, VERBOSE_PREFIX_3 "CAPI/contr%d supports line interconnect\n",
 
5416
                                controller);
 
5417
                        cp->lineinterconnect = 1;
 
5418
                }
 
5419
                
 
5420
                if (cp->sservices == 1) {
 
5421
                        cc_verbose(3, 0, VERBOSE_PREFIX_3 "CAPI/contr%d supports supplementary services\n",
 
5422
                                controller);
 
5423
                        supported_sservices(cp);
 
5424
                }
 
5425
 
 
5426
                /* New profile options for e.g. RTP with Eicon DIVA */
 
5427
                privateoptions = read_capi_dword(&profile.manufacturer[0]);
 
5428
                cc_verbose(3, 0, VERBOSE_PREFIX_3 "CAPI/contr%d private options=0x%08x\n",
 
5429
                        controller, privateoptions);
 
5430
                if (privateoptions & 0x02) {
 
5431
                        cc_verbose(3, 0, VERBOSE_PREFIX_4 "VoIP/RTP is supported\n");
 
5432
                        voice_over_ip_profile(cp);
 
5433
                }
 
5434
                if (privateoptions & 0x04) {
 
5435
                        cc_verbose(3, 0, VERBOSE_PREFIX_4 "T.38 is supported (not implemented yet)\n");
 
5436
                }
 
5437
 
2684
5438
                capi_controllers[controller] = cp;
2685
 
                if (cp->sservices == 1) {
2686
 
                    if (option_verbose > 3)
2687
 
                        ast_verbose(VERBOSE_PREFIX_3 "CAPI[contr%d] supports supplementary services\n",controller);
2688
 
                    supported_sservices(cp);
2689
 
                }
2690
 
            }
2691
 
        }
2692
 
 
2693
 
        v = ast_variable_browse(cfg, "interfaces");
2694
 
        while(v) {
2695
 
                /* Create the interface list */
2696
 
                if (!strcasecmp(v->name, "devices")) {
2697
 
#ifdef DEFLECT_ON_CIRCUITBUSY
2698
 
                        if (mkif(msn,incomingmsn,context,controllerstr,atoi(v->value),softdtmf,echocancel,ecoption,ectail, prefix, isdnmode, es,rxgain,txgain,deflect2,accountcode,callgroup)) {
2699
 
#else
2700
 
                        if (mkif(msn,incomingmsn,context,controllerstr,atoi(v->value),softdtmf,echocancel,ecoption,ectail, prefix, isdnmode, es,rxgain,txgain,accountcode,callgroup)) {
2701
 
#endif
2702
 
                            ast_log(LOG_ERROR,"Error creating interface list\n");
2703
 
                            return -1;
2704
 
                        }
2705
 
                        es=0; 
2706
 
                        strncpy(deflect2, empty, sizeof(deflect2)-1);
2707
 
                } else if (!strcasecmp(v->name, "context")) {
2708
 
                        strncpy(context, v->value, sizeof(context)-1);
2709
 
                } else if (!strcasecmp(v->name, "msn")) {
2710
 
                        strncpy(msn, v->value, sizeof(msn)-1);
2711
 
                } else if (!strcasecmp(v->name, "incomingmsn")) {
2712
 
                        strncpy(incomingmsn, v->value, sizeof(incomingmsn)-1);
2713
 
                } else if (!strcasecmp(v->name, "controller")) {
2714
 
                        strncpy(controllerstr, v->value, sizeof(controllerstr)-1);
2715
 
                } else if (!strcasecmp(v->name, "softdtmf")) {
2716
 
                        softdtmf = atoi(v->value);
2717
 
                } else if (!strcasecmp(v->name, "echosquelch")) {
2718
 
                        es = atoi(v->value);
2719
 
                } else if (!strcasecmp(v->name, "callgroup")) {
2720
 
                        callgroup = ast_get_group(v->value);
2721
 
                } else if (!strcasecmp(v->name, "deflect")) {
2722
 
                        strncpy(deflect2, v->value, sizeof(deflect2)-1);
2723
 
                } else if (!strcasecmp(v->name, "rxgain")) {
2724
 
                        if (sscanf(v->value,"%f",&rxgain) != 1) {
2725
 
                            ast_log(LOG_ERROR,"invalid rxgain\n");
2726
 
                        }
2727
 
                } else if (!strcasecmp(v->name, "txgain")) {
2728
 
                        if (sscanf(v->value,"%f",&txgain) != 1) {
2729
 
                            ast_log(LOG_ERROR,"invalid txgain\n");
2730
 
                        }
2731
 
                } else if (!strcasecmp(v->name, "echocancel")) {
2732
 
                        if (!strcasecmp(v->value, "yes") || !strcasecmp(v->value, "1") || !strcasecmp(v->value, "on")) {
2733
 
                                echocancel=1;
2734
 
                                ecoption=EC_OPTION_DISABLE_G165;
 
5439
        }
 
5440
        return 0;
 
5441
}
 
5442
 
 
5443
/*
 
5444
 * final capi init
 
5445
 */
 
5446
static int cc_post_init_capi(void)
 
5447
{
 
5448
        struct capi_pvt *i;
 
5449
        int controller;
 
5450
        unsigned error;
 
5451
        int use_rtp = 0;
 
5452
 
 
5453
        for (i = iflist; i && !use_rtp; i = i->next) {
 
5454
                /* if at least one line wants RTP, we need to re-register with
 
5455
                   bigger block size for RTP-header */
 
5456
                if (capi_controllers[i->controller]->rtpcodec & i->capability) {
 
5457
                        cc_verbose(3, 0, VERBOSE_PREFIX_4 "at least one CAPI controller wants RTP.\n");
 
5458
                        use_rtp = 1;
 
5459
                }
 
5460
        }
 
5461
        if (use_rtp) {
 
5462
                if (cc_register_capi(CAPI_MAX_B3_BLOCK_SIZE + RTP_HEADER_SIZE))
 
5463
                        return -1;
 
5464
        }
 
5465
 
 
5466
        for (controller = 1; controller <= capi_num_controllers; controller++) {
 
5467
                if (capi_used_controllers & (1 << controller)) {
 
5468
                        if ((error = ListenOnController(ALL_SERVICES, controller)) != 0) {
 
5469
                                cc_log(LOG_ERROR,"Unable to listen on contr%d (error=0x%x)\n",
 
5470
                                        controller, error);
 
5471
                        } else {
 
5472
                                cc_verbose(2, 0, VERBOSE_PREFIX_3 "listening on contr%d CIPmask = %#x\n",
 
5473
                                        controller, ALL_SERVICES);
 
5474
                        }
 
5475
                } else {
 
5476
                        cc_log(LOG_NOTICE, "Unused contr%d\n",controller);
 
5477
                }
 
5478
        }
 
5479
 
 
5480
        return 0;
 
5481
}
 
5482
 
 
5483
/*
 
5484
 * build the interface according to configs
 
5485
 */
 
5486
static int conf_interface(struct cc_capi_conf *conf, struct ast_variable *v)
 
5487
{
 
5488
        int y;
 
5489
 
 
5490
#define CONF_STRING(var, token)            \
 
5491
        if (!strcasecmp(v->name, token)) { \
 
5492
                cc_copy_string(var, v->value, sizeof(var)); \
 
5493
                continue;                  \
 
5494
        } else
 
5495
#define CONF_INTEGER(var, token)           \
 
5496
        if (!strcasecmp(v->name, token)) { \
 
5497
                var = atoi(v->value);      \
 
5498
                continue;                  \
 
5499
        } else
 
5500
#define CONF_TRUE(var, token, val)         \
 
5501
        if (!strcasecmp(v->name, token)) { \
 
5502
                if (ast_true(v->value))    \
 
5503
                        var = val;         \
 
5504
                continue;                  \
 
5505
        } else
 
5506
 
 
5507
        for (; v; v = v->next) {
 
5508
                CONF_INTEGER(conf->devices, "devices")
 
5509
                CONF_STRING(conf->context, "context")
 
5510
                CONF_STRING(conf->incomingmsn, "incomingmsn")
 
5511
                CONF_STRING(conf->defaultcid, "defaultcid")
 
5512
                CONF_STRING(conf->controllerstr, "controller")
 
5513
                CONF_STRING(conf->prefix, "prefix")
 
5514
                CONF_STRING(conf->accountcode, "accountcode")
 
5515
                CONF_STRING(conf->language, "language")
 
5516
 
 
5517
                if (!strcasecmp(v->name, "softdtmf")) {
 
5518
                        if ((!conf->softdtmf) && (ast_true(v->value))) {
 
5519
                                conf->softdtmf = 1;
 
5520
                        }
 
5521
                        continue;
 
5522
                } else
 
5523
                CONF_TRUE(conf->softdtmf, "relaxdtmf", 2)
 
5524
                if (!strcasecmp(v->name, "holdtype")) {
 
5525
                        if (!strcasecmp(v->value, "hold")) {
 
5526
                                conf->holdtype = CC_HOLDTYPE_HOLD;
 
5527
                        } else if (!strcasecmp(v->value, "notify")) {
 
5528
                                conf->holdtype = CC_HOLDTYPE_NOTIFY;
 
5529
                        } else {
 
5530
                                conf->holdtype = CC_HOLDTYPE_LOCAL;
 
5531
                        }
 
5532
                        continue;
 
5533
                } else
 
5534
                CONF_TRUE(conf->immediate, "immediate", 1)
 
5535
                CONF_TRUE(conf->es, "echosquelch", 1)
 
5536
                CONF_TRUE(conf->bridge, "bridge", 1)
 
5537
                CONF_TRUE(conf->ntmode, "ntmode", 1)
 
5538
                if (!strcasecmp(v->name, "callgroup")) {
 
5539
                        conf->callgroup = ast_get_group(v->value);
 
5540
                        continue;
 
5541
                } else
 
5542
                if (!strcasecmp(v->name, "pickupgroup")) {
 
5543
                        conf->pickupgroup = ast_get_group(v->value);
 
5544
                        continue;
 
5545
                } else
 
5546
                if (!strcasecmp(v->name, "group")) {
 
5547
                        conf->group = ast_get_group(v->value);
 
5548
                        continue;
 
5549
                } else
 
5550
                if (!strcasecmp(v->name, "amaflags")) {
 
5551
                        y = ast_cdr_amaflags2int(v->value);
 
5552
                        if (y < 0) {
 
5553
                                ast_log(LOG_WARNING, "Invalid AMA flags: %s at line %d\n",
 
5554
                                        v->value, v->lineno);
 
5555
                        } else {
 
5556
                                conf->amaflags = y;
 
5557
                        }
 
5558
                } else
 
5559
                if (!strcasecmp(v->name, "rxgain")) {
 
5560
                        if (sscanf(v->value, "%f", &conf->rxgain) != 1) {
 
5561
                                cc_log(LOG_ERROR,"invalid rxgain\n");
 
5562
                        }
 
5563
                        continue;
 
5564
                } else
 
5565
                if (!strcasecmp(v->name, "txgain")) {
 
5566
                        if (sscanf(v->value, "%f", &conf->txgain) != 1) {
 
5567
                                cc_log(LOG_ERROR, "invalid txgain\n");
 
5568
                        }
 
5569
                        continue;
 
5570
                } else
 
5571
                if (!strcasecmp(v->name, "echocancelold")) {
 
5572
                        if (ast_true(v->value)) {
 
5573
                                conf->ecSelector = 6;
 
5574
                        }
 
5575
                        continue;
 
5576
                } else
 
5577
                if (!strcasecmp(v->name, "faxdetect")) {
 
5578
                        if (!strcasecmp(v->value, "incoming")) {
 
5579
                                conf->faxsetting |= CAPI_FAX_DETECT_INCOMING;
 
5580
                                conf->faxsetting &= ~CAPI_FAX_DETECT_OUTGOING;
 
5581
                        } else if (!strcasecmp(v->value, "outgoing")) {
 
5582
                                conf->faxsetting |= CAPI_FAX_DETECT_OUTGOING;
 
5583
                                conf->faxsetting &= ~CAPI_FAX_DETECT_INCOMING;
 
5584
                        } else if (!strcasecmp(v->value, "both") || ast_true(v->value))
 
5585
                                conf->faxsetting |= (CAPI_FAX_DETECT_OUTGOING | CAPI_FAX_DETECT_INCOMING);
 
5586
                        else
 
5587
                                conf->faxsetting &= ~(CAPI_FAX_DETECT_OUTGOING | CAPI_FAX_DETECT_INCOMING);
 
5588
                } else
 
5589
                if (!strcasecmp(v->name, "echocancel")) {
 
5590
                        if (ast_true(v->value)) {
 
5591
                                conf->echocancel = 1;
 
5592
                                conf->ecoption = EC_OPTION_DISABLE_G165;
2735
5593
                        }       
2736
 
                        else if (!strcasecmp(v->value, "no") || !strcasecmp(v->value, "0") || !strcasecmp(v->value, "off")) {
2737
 
                                echocancel=0;
2738
 
                                ecoption=0;
 
5594
                        else if (ast_false(v->value)) {
 
5595
                                conf->echocancel = 0;
 
5596
                                conf->ecoption = 0;
2739
5597
                        }       
2740
5598
                        else if (!strcasecmp(v->value, "g165") || !strcasecmp(v->value, "g.165")) {
2741
 
                                echocancel=1;
2742
 
                                ecoption=EC_OPTION_DISABLE_G165;
 
5599
                                conf->echocancel = 1;
 
5600
                                conf->ecoption = EC_OPTION_DISABLE_G165;
2743
5601
                        }       
2744
5602
                        else if (!strcasecmp(v->value, "g164") || !strcasecmp(v->value, "g.164")) {
2745
 
                                echocancel=1;
2746
 
                                ecoption=EC_OPTION_DISABLE_G164_OR_G165;
 
5603
                                conf->echocancel = 1;
 
5604
                                conf->ecoption = EC_OPTION_DISABLE_G164_OR_G165;
2747
5605
                        }       
2748
5606
                        else if (!strcasecmp(v->value, "force")) {
2749
 
                                echocancel=1;
2750
 
                                ecoption=EC_OPTION_DISABLE_NEVER;
 
5607
                                conf->echocancel = 1;
 
5608
                                conf->ecoption = EC_OPTION_DISABLE_NEVER;
2751
5609
                        }
2752
5610
                        else {
2753
 
                                ast_log(LOG_ERROR,"Unknown echocancel parameter \"%s\" -- ignoring\n",v->value);
 
5611
                                cc_log(LOG_ERROR,"Unknown echocancel parameter \"%s\" -- ignoring\n",v->value);
2754
5612
                        }
2755
 
                } else if (!strcasecmp(v->name, "echotail")) {
2756
 
                        ectail = atoi(v->value);
2757
 
                        if (ectail > 255)
2758
 
                                ectail = 255;
2759
 
                } else if (!strcasecmp(v->name, "prefix")) {
2760
 
                        strncpy(prefix, v->value, sizeof(prefix)-1);
2761
 
                } else if (!strcasecmp(v->name, "accountcode")) {
2762
 
                        strncpy(accountcode, v->value, sizeof(accountcode)-1);
2763
 
                } else if (!strcasecmp(v->name, "isdnmode")) {
2764
 
                        if (!strcasecmp(v->value, "ptp") || !strcasecmp(v->value, "1"))
2765
 
                            isdnmode = 1;
2766
 
                        else if (!strcasecmp(v->value, "ptm") || !strcasecmp(v->value, "1"))
2767
 
                            isdnmode = 0;
 
5613
                        continue;
 
5614
                } else
 
5615
                CONF_TRUE(conf->ecnlp, "echocancelnlp", 1)
 
5616
                if (!strcasecmp(v->name, "echotail")) {
 
5617
                        conf->ectail = atoi(v->value);
 
5618
                        if (conf->ectail > 255) {
 
5619
                                conf->ectail = 255;
 
5620
                        } 
 
5621
                        continue;
 
5622
                } else
 
5623
                if (!strcasecmp(v->name, "isdnmode")) {
 
5624
                        if (!strcasecmp(v->value, "did"))
 
5625
                            conf->isdnmode = CAPI_ISDNMODE_DID;
 
5626
                        else if (!strcasecmp(v->value, "msn"))
 
5627
                            conf->isdnmode = CAPI_ISDNMODE_MSN;
2768
5628
                        else
2769
 
                            ast_log(LOG_ERROR,"Unknown isdnmode parameter \"%s\" -- ignoring\n",v->value);
2770
 
 
2771
 
                }
2772
 
 
2773
 
                v = v->next;
2774
 
        }
2775
 
        ast_destroy(cfg);
2776
 
 
2777
 
            for (controller=1;controller<=capi_num_controllers;controller++) {
 
5629
                            cc_log(LOG_ERROR,"Unknown isdnmode parameter \"%s\" -- ignoring\n",
 
5630
                                v->value);
 
5631
                } else
 
5632
                if (!strcasecmp(v->name, "allow")) {
 
5633
                        ast_parse_allow_disallow(&conf->prefs, &conf->capability, v->value, 1);
 
5634
                } else
 
5635
                if (!strcasecmp(v->name, "disallow")) {
 
5636
                        ast_parse_allow_disallow(&conf->prefs, &conf->capability, v->value, 0);
 
5637
                }
 
5638
        }
 
5639
#undef CONF_STRING
 
5640
#undef CONF_INTEGER
 
5641
#undef CONF_TRUE
 
5642
        return 0;
 
5643
}
 
5644
 
 
5645
/*
 
5646
 * load the config
 
5647
 */
 
5648
static int capi_eval_config(struct ast_config *cfg)
 
5649
{
 
5650
        struct cc_capi_conf conf;
 
5651
        struct ast_variable *v;
 
5652
        char *cat = NULL;
 
5653
        float rxgain = 1.0;
 
5654
        float txgain = 1.0;
 
5655
 
 
5656
        /* prefix defaults */
 
5657
        cc_copy_string(capi_national_prefix, CAPI_NATIONAL_PREF, sizeof(capi_national_prefix));
 
5658
        cc_copy_string(capi_international_prefix, CAPI_INTERNAT_PREF, sizeof(capi_international_prefix));
 
5659
 
 
5660
        /* read the general section */
 
5661
        for (v = ast_variable_browse(cfg, "general"); v; v = v->next) {
 
5662
                if (!strcasecmp(v->name, "nationalprefix")) {
 
5663
                        cc_copy_string(capi_national_prefix, v->value, sizeof(capi_national_prefix));
 
5664
                } else if (!strcasecmp(v->name, "internationalprefix")) {
 
5665
                        cc_copy_string(capi_international_prefix, v->value, sizeof(capi_international_prefix));
 
5666
                } else if (!strcasecmp(v->name, "language")) {
 
5667
                        cc_copy_string(default_language, v->value, sizeof(default_language));
 
5668
                } else if (!strcasecmp(v->name, "rxgain")) {
 
5669
                        if (sscanf(v->value,"%f",&rxgain) != 1) {
 
5670
                                cc_log(LOG_ERROR,"invalid rxgain\n");
 
5671
                        }
 
5672
                } else if (!strcasecmp(v->name, "txgain")) {
 
5673
                        if (sscanf(v->value,"%f",&txgain) != 1) {
 
5674
                                cc_log(LOG_ERROR,"invalid txgain\n");
 
5675
                        }
 
5676
                } else if (!strcasecmp(v->name, "ulaw")) {
 
5677
                        if (ast_true(v->value)) {
 
5678
                                capi_capability = AST_FORMAT_ULAW;
 
5679
                        }
 
5680
                }
 
5681
        }
 
5682
 
 
5683
        /* go through all other sections, which are our interfaces */
 
5684
        for (cat = ast_category_browse(cfg, NULL); cat; cat = ast_category_browse(cfg, cat)) {
 
5685
                if (!strcasecmp(cat, "general"))
 
5686
                        continue;
 
5687
                        
 
5688
                if (!strcasecmp(cat, "interfaces")) {
 
5689
                        cc_log(LOG_WARNING, "Config file syntax has changed! Don't use 'interfaces'\n");
 
5690
                        return -1;
 
5691
                }
 
5692
                cc_verbose(4, 0, VERBOSE_PREFIX_2 "Reading config for %s\n",
 
5693
                        cat);
 
5694
                
 
5695
                /* init the conf struct */
 
5696
                memset(&conf, 0, sizeof(conf));
 
5697
                conf.rxgain = rxgain;
 
5698
                conf.txgain = txgain;
 
5699
                conf.ecoption = EC_OPTION_DISABLE_G165;
 
5700
                conf.ectail = EC_DEFAULT_TAIL;
 
5701
                conf.ecSelector = FACILITYSELECTOR_ECHO_CANCEL;
 
5702
                cc_copy_string(conf.name, cat, sizeof(conf.name));
 
5703
                cc_copy_string(conf.language, default_language, sizeof(conf.language));
 
5704
 
 
5705
                if (conf_interface(&conf, ast_variable_browse(cfg, cat))) {
 
5706
                        cc_log(LOG_ERROR, "Error interface config.\n");
 
5707
                        return -1;
 
5708
                }
 
5709
 
 
5710
                if (mkif(&conf)) {
 
5711
                        cc_log(LOG_ERROR,"Error creating interface list\n");
 
5712
                        return -1;
 
5713
                }
 
5714
        }
 
5715
        return 0;
 
5716
}
 
5717
 
 
5718
/*
 
5719
 * unload the module
 
5720
 */
 
5721
int unload_module()
 
5722
{
 
5723
        struct capi_pvt *i, *itmp;
 
5724
        int controller;
 
5725
 
 
5726
        ast_unregister_application(commandapp);
 
5727
 
 
5728
        ast_cli_unregister(&cli_info);
 
5729
        ast_cli_unregister(&cli_show_channels);
 
5730
        ast_cli_unregister(&cli_debug);
 
5731
        ast_cli_unregister(&cli_no_debug);
 
5732
 
 
5733
        if (monitor_thread != (pthread_t)(0-1)) {
 
5734
                pthread_cancel(monitor_thread);
 
5735
                pthread_kill(monitor_thread, SIGURG);
 
5736
                pthread_join(monitor_thread, NULL);
 
5737
        }
 
5738
 
 
5739
        cc_mutex_lock(&iflock);
 
5740
 
 
5741
        if (capi_ApplID != CAPI_APPLID_UNUSED) {
 
5742
                if (capi20_release(capi_ApplID) != 0)
 
5743
                        cc_log(LOG_WARNING,"Unable to unregister from CAPI!\n");
 
5744
        }
 
5745
 
 
5746
        for (controller = 1; controller <= capi_num_controllers; controller++) {
2778
5747
                if (capi_used_controllers & (1 << controller)) {
2779
 
                    if (ListenOnController(ALL_SERVICES,controller) != 0) {
2780
 
                        ast_log(LOG_ERROR,"Unable to listen on contr%d\n",controller);
2781
 
                    } else {
2782
 
                        if (option_verbose > 2) 
2783
 
                            ast_verbose(VERBOSE_PREFIX_3 "listening on contr%d CIPmask = %#x\n",controller,ALL_SERVICES);
2784
 
                    }
2785
 
                } else {
2786
 
                    ast_log(LOG_WARNING,"Unused contr%d\n",controller);
 
5748
                        if (capi_controllers[controller])
 
5749
                                free(capi_controllers[controller]);
2787
5750
                }
2788
 
            }
2789
 
 
2790
 
 
2791
 
        ast_mutex_unlock(&iflock);
2792
 
        
2793
 
        if (ast_channel_register(type, tdesc, capi_capability, capi_request)) {
2794
 
                ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
 
5751
        }
 
5752
        
 
5753
        i = iflist;
 
5754
        while (i) {
 
5755
                if (i->owner)
 
5756
                        cc_log(LOG_WARNING, "On unload, interface still has owner.\n");
 
5757
                if (i->smoother)
 
5758
                        ast_smoother_free(i->smoother);
 
5759
                cc_mutex_destroy(&i->lock);
 
5760
                ast_cond_destroy(&i->event_trigger);
 
5761
                itmp = i;
 
5762
                i = i->next;
 
5763
                free(itmp);
 
5764
        }
 
5765
 
 
5766
        cc_mutex_unlock(&iflock);
 
5767
        
 
5768
        ast_channel_unregister(&capi_tech);
 
5769
        
 
5770
        return 0;
 
5771
}
 
5772
 
 
5773
/*
 
5774
 * main: load the module
 
5775
 */
 
5776
int load_module(void)
 
5777
{
 
5778
        struct ast_config *cfg;
 
5779
        char *config = "capi.conf";
 
5780
        int res = 0;
 
5781
 
 
5782
        cfg = ast_config_load(config);
 
5783
 
 
5784
        /* We *must* have a config file otherwise stop immediately, well no */
 
5785
        if (!cfg) {
 
5786
                cc_log(LOG_ERROR, "Unable to load config %s, CAPI disabled\n", config);
 
5787
                return 0;
 
5788
        }
 
5789
 
 
5790
        if (cc_mutex_lock(&iflock)) {
 
5791
                cc_log(LOG_ERROR, "Unable to lock interface list???\n");
 
5792
                return -1;
 
5793
        }
 
5794
 
 
5795
        if ((res = cc_init_capi()) != 0) {
 
5796
                cc_mutex_unlock(&iflock);
 
5797
                return(res);
 
5798
        }
 
5799
 
 
5800
        res = capi_eval_config(cfg);
 
5801
        ast_config_destroy(cfg);
 
5802
 
 
5803
        if (res != 0) {
 
5804
                cc_mutex_unlock(&iflock);
 
5805
                return(res);
 
5806
        }
 
5807
 
 
5808
        if ((res = cc_post_init_capi()) != 0) {
 
5809
                cc_mutex_unlock(&iflock);
 
5810
                unload_module();
 
5811
                return(res);
 
5812
        }
 
5813
        
 
5814
        cc_mutex_unlock(&iflock);
 
5815
        
 
5816
        if (ast_channel_register(&capi_tech)) {
 
5817
                cc_log(LOG_ERROR, "Unable to register channel class %s\n", channeltype);
2795
5818
                unload_module();
2796
5819
                return -1;
2797
5820
        }
2798
5821
 
2799
5822
        ast_cli_register(&cli_info);
 
5823
        ast_cli_register(&cli_show_channels);
2800
5824
        ast_cli_register(&cli_debug);
2801
5825
        ast_cli_register(&cli_no_debug);
2802
5826
        
2803
 
        restart_monitor();
2804
 
 
2805
 
        return res;
2806
 
}
2807
 
 
2808
 
 
2809
 
int unload_module()
2810
 
{
2811
 
        if (capi20_release(ast_capi_ApplID) != 0)
2812
 
                ast_log(LOG_WARNING,"Unable to unregister from CAPI!\n");
2813
 
        ast_channel_unregister(type);
 
5827
        ast_register_application(commandapp, pbx_capicommand_exec, commandsynopsis, commandtdesc);
 
5828
 
 
5829
        if (ast_pthread_create(&monitor_thread, NULL, capidev_loop, NULL) < 0) {
 
5830
                monitor_thread = (pthread_t)(0-1);
 
5831
                cc_log(LOG_ERROR, "Unable to start monitor thread!\n");
 
5832
                return -1;
 
5833
        }
 
5834
 
2814
5835
        return 0;
2815
5836
}
2816
5837
 
2817
5838
int usecount()
2818
5839
{
2819
5840
        int res;
2820
 
        ast_mutex_lock(&usecnt_lock);
 
5841
        
 
5842
        cc_mutex_lock(&usecnt_lock);
2821
5843
        res = usecnt;
2822
 
        ast_mutex_unlock(&usecnt_lock);
 
5844
        cc_mutex_unlock(&usecnt_lock);
 
5845
 
2823
5846
        return res;
2824
5847
}
2825
5848
 
2826
5849
char *description()
2827
5850
{
2828
 
        return desc;
 
5851
        return ccdesc;
2829
5852
}
2830
5853
 
2831
 
 
 
5854
#ifndef PBX_IS_OPBX
2832
5855
char *key()
2833
5856
{
2834
5857
        return ASTERISK_GPL_KEY;
2835
5858
}
 
5859
#endif