23
72
#include <asterisk/features.h>
24
73
#include <asterisk/utils.h>
25
74
#include <asterisk/cli.h>
27
#include <sys/signal.h>
34
#include <sys/types.h>
35
#include <linux/capi.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>
39
#include "chan_capi_pvt.h"
41
unsigned ast_capi_ApplID;
42
_cword ast_capi_MessageNumber=1;
43
static char *desc = "Common ISDN API for Asterisk";
46
static char *tdesc = "Common ISDN API Driver (0.3.5) muLaw CVS HEAD";
48
static char *tdesc = "Common ISDN API Driver (0.3.5) muLaw";
52
static char *tdesc = "Common ISDN API Driver (0.3.5) aLaw CVS HEAD";
54
static char *tdesc = "Common ISDN API Driver (0.3.5) aLaw";
57
static char *type = "CAPI";
81
#include "chan_capi20.h"
82
#include "chan_capi.h"
83
#include "chan_capi_rtp.h"
87
#define CC_VERSION "cm-opbx-0.7"
89
#define CC_VERSION "0.7.1"
90
/* #define CC_VERSION "$Revision: 392 $" */
96
#undef CAPI_APPLID_UNUSED
97
#define CAPI_APPLID_UNUSED 0xffffffff
98
unsigned capi_ApplID = CAPI_APPLID_UNUSED;
100
static _cword capi_MessageNumber;
102
static char *ccdesc = "Common ISDN API for OpenPBX";
104
static char *ccdesc = "Common ISDN API for Asterisk";
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;
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"
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"
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";
144
static char *commandapp = "capiCommand";
145
static char *commandsynopsis = "Execute special CAPI commands";
60
149
static int usecnt;
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:
160
* struct capi_pvt *i;
162
* 1. cc_mutex_lock(&i->owner->lock); **
164
* 2. cc_mutex_lock(&i->lock);
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);
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
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);
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;
183
AST_MUTEX_DEFINE_STATIC(verbose_lock);
80
static int capi_capability = AST_FORMAT_ULAW;
82
185
static int capi_capability = AST_FORMAT_ALAW;
84
static struct ast_capi_profile profile;
86
static pthread_t monitor_thread = -1;
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];
187
static pthread_t monitor_thread = (pthread_t)(0-1);
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;
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;
99
char capi_national_prefix[AST_MAX_EXTENSION];
100
char capi_international_prefix[AST_MAX_EXTENSION];
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");
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");
119
MESSAGE_EXCHANGE_ERROR check_wait_get_cmsg(_cmsg *CMSG) {
120
MESSAGE_EXCHANGE_ERROR Info;
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";
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
203
static char capi_national_prefix[AST_MAX_EXTENSION];
204
static char capi_international_prefix[AST_MAX_EXTENSION];
206
static char default_language[MAX_LANGUAGE] = "";
208
static int capidebug = 0;
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);
214
static int pbx_capi_indicate(struct ast_channel *c, int condition);
217
/* external prototypes */
218
extern char *capi_info_string(unsigned int info);
221
#define return_on_no_interface(x) \
223
cc_verbose(4, 1, "CAPI: %s no interface for PLCI=%#x\n", x, PLCI); \
228
* helper for <pbx>_verbose with different verbose settings
230
void cc_verbose(int o_v, int c_d, char *text, ...)
236
vsnprintf(line, sizeof(line), text, ap);
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);
249
* B protocol settings
255
_cstruct b1configuration;
256
_cstruct b2configuration;
257
_cstruct b3configuration;
258
} b_protocol_table[] =
260
{ 0x01, 0x01, 0x00, /* 0 */
265
{ 0x04, 0x04, 0x04, /* 1 */
270
{ 0x1f, 0x1f, 0x1f, /* 2 */
272
/* (_cstruct) "\x04\x01\x00\x00\x02", */
273
(_cstruct) "\x06\x01\x00\x58\x02\x32\x00",
278
#ifndef CC_HAVE_NO_GLOBALCONFIGURATION
280
* set the global-configuration (b-channel operation)
282
static _cstruct capi_set_global_configuration(struct capi_pvt *i)
284
unsigned short dtedce = 0;
285
unsigned char *buf = i->tmpbuf;
287
buf[0] = 2; /* len */
289
if (i->FaxState & CAPI_FAX_STATE_ACTIVE) {
290
if ((i->outgoing) && (!(i->FaxState & CAPI_FAX_STATE_SENDMODE)))
292
if ((!(i->outgoing)) && ((i->FaxState & CAPI_FAX_STATE_SENDMODE)))
295
write_capi_word(&buf[1], dtedce);
298
return (_cstruct)buf;
303
* command to string function
305
static const char * capi_command_to_string(unsigned short wCmd)
307
enum { lowest_value = CAPI_P_MIN,
308
end_value = CAPI_P_MAX,
309
range = end_value - lowest_value,
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",
319
static const char * const table[range] = {
320
CAPI_COMMANDS(CHAN_CAPI_COMMAND_DESC, lowest_value)
323
wCmd -= lowest_value;
329
if (table[wCmd] == NULL) {
339
* show the text for a CAPI message info value
341
static void show_capi_info(struct capi_pvt *i, _cword info)
346
if (info == 0x0000) {
347
/* no error, do nothing */
351
if (!(p = capi_info_string((unsigned int)info))) {
352
/* message not available */
359
cc_verbose(3, 0, VERBOSE_PREFIX_4 "%s: CAPI INFO 0x%04x: %s\n",
365
* get a new capi message number automically
367
_cword get_capi_MessageNumber(void)
371
cc_mutex_lock(&messagenumber_lock);
373
capi_MessageNumber++;
374
if (capi_MessageNumber == 0) {
376
capi_MessageNumber = 1;
379
mn = capi_MessageNumber;
381
cc_mutex_unlock(&messagenumber_lock);
387
* write a capi message to capi device
389
MESSAGE_EXCHANGE_ERROR _capi_put_cmsg(_cmsg *CMSG)
391
MESSAGE_EXCHANGE_ERROR error;
393
if (cc_mutex_lock(&capi_put_lock)) {
394
cc_log(LOG_WARNING, "Unable to lock capi put!\n");
398
error = capi20_put_cmsg(CMSG);
400
if (cc_mutex_unlock(&capi_put_lock)) {
401
cc_log(LOG_WARNING, "Unable to unlock capi put!\n");
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));
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));
415
cc_verbose(4, 1, "%s\n", capi_cmsg2str(CMSG));
423
* wait for a specific message
425
static MESSAGE_EXCHANGE_ERROR capi_wait_conf(struct capi_pvt *i, unsigned short wCmd)
427
MESSAGE_EXCHANGE_ERROR error = 0;
428
struct timespec abstime;
429
unsigned char command, subcommand;
431
subcommand = wCmd & 0xff;
432
command = (wCmd & 0xff00) >> 8;
433
i->waitevent = (unsigned int)wCmd;
434
abstime.tv_sec = time(NULL) + 2;
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) {
440
cc_log(LOG_WARNING, "%s: timed out waiting for %s\n",
441
i->vname, capi_cmd2str(command, subcommand));
443
cc_verbose(4, 1, "%s: cond signal received for %s\n",
444
i->vname, capi_cmd2str(command, subcommand));
450
* write a capi message and wait for CONF
451
* i->lock must be held
453
MESSAGE_EXCHANGE_ERROR _capi_put_cmsg_wait_conf(struct capi_pvt *i, _cmsg *CMSG)
455
MESSAGE_EXCHANGE_ERROR error;
457
error = _capi_put_cmsg(CMSG);
460
unsigned short wCmd = CAPICMD(CMSG->Command, CAPI_CONF);
461
error = capi_wait_conf(i, wCmd);
469
static void capi_wait_for_b3_up(struct capi_pvt *i)
471
struct timespec abstime;
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;
478
cc_verbose(4, 1, "%s: wait for b3 up.\n",
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",
484
cc_verbose(4, 1, "%s: cond signal received for b3 up.\n",
488
cc_mutex_unlock(&i->lock);
492
* wait for finishing answering state
494
static void capi_wait_for_answered(struct capi_pvt *i)
496
struct timespec abstime;
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;
503
cc_verbose(4, 1, "%s: wait for finish answer.\n",
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",
509
cc_verbose(4, 1, "%s: cond signal received for finish answer.\n",
513
cc_mutex_unlock(&i->lock);
517
* wait until fax activity has finished
519
static void capi_wait_for_fax_finish(struct capi_pvt *i)
521
struct timespec abstime;
522
unsigned int timeout = 600; /* 10 minutes, to be sure */
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;
529
cc_verbose(4, 1, "%s: wait for finish fax (timeout %d seconds).\n",
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",
535
cc_verbose(4, 1, "%s: cond signal received for finish fax.\n",
539
cc_mutex_unlock(&i->lock);
543
* wait some time for a new capi message
545
static MESSAGE_EXCHANGE_ERROR capidev_check_wait_get_cmsg(_cmsg *CMSG)
547
MESSAGE_EXCHANGE_ERROR Info;
551
Info = capi_get_cmsg(CMSG, capi_ApplID);
553
#if (CAPI_OS_HINT == 1) || (CAPI_OS_HINT == 2)
555
* For BSD allow controller 0:
557
if ((HEADER_CID(CMSG) & 0xFF) == 0) {
558
HEADER_CID(CMSG) += capi_num_controllers;
562
/* if queue is empty */
563
if (Info == 0x1104) {
564
/* try waiting a maximum of 0.100 seconds for a message */
568
Info = capi20_waitformessage(capi_ApplID, &tv);
574
if ((Info != 0x0000) && (Info != 0x1104)) {
576
cc_log(LOG_DEBUG, "Error waiting for cmsg... INFO = %#x\n", Info);
130
if (Info == 0x0000) {
131
Info = capi_get_cmsg(CMSG,ast_capi_ApplID);
137
unsigned ListenOnController(unsigned long CIPmask,unsigned controller) {
138
MESSAGE_EXCHANGE_ERROR error;
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 ;)
145
LISTEN_REQ_INFOMASK(&CMSG) = 0x03ff; // lots of info ;) + early B3 connect
147
LISTEN_REQ_CIPMASK(&CMSG) = CIPmask;
148
if ((error = _capi_put_cmsg(&CMSG)) != 0) {
584
* send Listen to specified controller
586
static unsigned ListenOnController(unsigned long CIPmask, unsigned controller)
588
MESSAGE_EXCHANGE_ERROR error;
592
LISTEN_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(), controller);
594
LISTEN_REQ_INFOMASK(&CMSG) = 0xffff; /* lots of info ;) + early B3 connect */
595
/* 0x00ff if no early B3 should be done */
597
LISTEN_REQ_CIPMASK(&CMSG) = CIPmask;
598
error = _capi_put_cmsg(&CMSG);
604
error = capidev_check_wait_get_cmsg(&CMSG);
606
if (IS_LISTEN_CONF(&CMSG)) {
607
error = LISTEN_CONF_INFO(&CMSG);
151
while (!IS_LISTEN_CONF(&CMSG2)) {
152
error = check_wait_get_cmsg(&CMSG2);
157
unsigned Listen(unsigned long CIPmask) {
158
return ListenOnController(CIPmask,0);
161
// Echo cancellation is for cards w/ integrated echo cancellation only
162
// (i.e. Eicon active cards support it)
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
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;
621
* TCAP -> CIP Translation Table (TransferCapability->CommonIsdnProfile)
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 }
636
static int tcap2cip(unsigned short tcap)
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;
644
return CAPI_CIPI_SPEECH;
647
static unsigned char tcap_is_digital(unsigned short tcap)
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;
659
* CIP -> TCAP Translation Table (CommonIsdnProfile->TransferCapability)
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 }
689
static unsigned short cip2tcap(int cip)
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;
701
* TransferCapability to String conversion
703
static char *transfercapability2str(int transfercapability)
705
switch(transfercapability) {
706
case PRI_TRANS_CAP_SPEECH:
708
case PRI_TRANS_CAP_DIGITAL:
710
case PRI_TRANS_CAP_RESTRICTED_DIGITAL:
711
return "RESTRICTED_DIGITAL";
712
case PRI_TRANS_CAP_3K1AUDIO:
714
case PRI_TRANS_CAP_DIGITAL_W_TONES:
715
return "DIGITAL_W_TONES";
716
case PRI_TRANS_CAP_VIDEO:
724
* set task for a channel which need to be done out of lock
725
* ( after the capi thread loop )
727
static void capi_channel_task(struct ast_channel *c, int task)
732
cc_verbose(4, 1, VERBOSE_PREFIX_4 "%s: set channel task to %d\n",
737
* Echo cancellation is for cards w/ integrated echo cancellation only
738
* (i.e. Eicon active cards support it)
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 */
750
static void capi_echo_canceller(struct ast_channel *c, int function)
752
struct capi_pvt *i = CC_CHANNEL_PVT(c);
756
if ((i->isdnstate & CAPI_ISDN_STATE_DISCONNECT))
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);
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);
186
ast_mutex_unlock(&contrlock);
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);
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 */
195
buf[0]=6; /* msg size */
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",
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);
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;
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 */
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;
795
i->isdnstate &= ~CAPI_ISDN_STATE_EC;
798
FACILITY_REQ_FACILITYREQUESTPARAMETER(&CMSG) = (_cstruct)buf;
213
if ((error = _capi_put_cmsg(&CMSG)) != 0) {
214
ast_log(LOG_ERROR,"error sending FACILITY_REQ (error=%#x)\n",error);
800
if (_capi_put_cmsg(&CMSG) != 0) {
218
if (option_verbose > 5)
219
ast_verbose(VERBOSE_PREFIX_4 "sent FACILITY_REQ (PLCI=%#x)\n",i->PLCI);
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;
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);
808
* turn on/off DTMF detection
810
static int capi_detect_dtmf(struct ast_channel *c, int flag)
812
struct capi_pvt *i = CC_CHANNEL_PVT(c);
813
MESSAGE_EXCHANGE_ERROR error;
817
if ((i->isdnstate & CAPI_ISDN_STATE_DISCONNECT))
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",
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);
834
/* does the controller support dtmf? and do we want to use it? */
835
if ((capi_controllers[i->controller]->dtmf != 1) || (i->doDTMF != 0))
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;
843
FACILITY_REQ_FACILITYSELECTOR(&CMSG) = FACILITYSELECTOR_DTMF;
844
buf[0] = 8; /* msg length */
846
write_capi_word(&buf[1], 1); /* start DTMF listen */
848
write_capi_word(&buf[1], 2); /* stop DTMF listen */
244
buf[3] = AST_CAPI_DTMF_DURATION;
246
buf[5] = AST_CAPI_DTMF_DURATION;
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;
252
854
if ((error = _capi_put_cmsg(&CMSG)) != 0) {
253
ast_log(LOG_ERROR,"error sending FACILITY_REQ (error=%#x)\n",error);
858
i->isdnstate |= CAPI_ISDN_STATE_DTMF;
256
if (option_verbose > 5) {
257
ast_verbose(VERBOSE_PREFIX_4 "sent FACILITY_REQ (PLCI=%#x)\n",i->PLCI);
261
ast_mutex_unlock(&contrlock);
264
// do software dtmf detection
265
i->doDTMF = 1; // just being paranoid again...
266
#ifndef FORCE_SOFTWARE_DTMF
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;
277
if (i->state != CAPI_STATE_BCONNECTED) {
282
#ifndef NEVER_EVER_EARLY_B3_CONNECTS
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 */
289
INFO_REQ_HEADER(&CMSG, ast_capi_ApplID, ast_capi_MessageNumber++, 0);
860
i->isdnstate &= ~CAPI_ISDN_STATE_DTMF;
866
* queue a frame to PBX
868
static int local_queue_frame(struct capi_pvt *i, struct ast_frame *f)
870
struct ast_channel *chan = i->owner;
875
cc_log(LOG_ERROR, "No owner in local_queue_frame for %s\n",
880
if (!(i->isdnstate & CAPI_ISDN_STATE_PBX)) {
881
/* if there is no PBX running yet,
882
we don't need any frames sent */
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);
892
if ((capidebug) && (f->frametype != AST_FRAME_VOICE)) {
893
ast_frame_dump(i->vname, f, VERBOSE_PREFIX_3 "CAPI queue frame:");
896
if ((f->frametype == AST_FRAME_CONTROL) &&
897
(f->subclass == AST_CONTROL_HANGUP)) {
898
i->isdnstate |= CAPI_ISDN_STATE_HANGUP;
901
if (i->writerfd == -1) {
902
cc_log(LOG_ERROR, "No writerfd in local_queue_frame for %s\n",
907
if (f->frametype != AST_FRAME_VOICE)
910
wbuflen = sizeof(struct ast_frame) + f->datalen;
911
wbuf = alloca(wbuflen);
912
memcpy(wbuf, f, sizeof(struct ast_frame));
914
memcpy(wbuf + sizeof(struct ast_frame), f->data, f->datalen);
916
if (write(i->writerfd, wbuf, wbuflen) != wbuflen) {
917
cc_log(LOG_ERROR, "Could not write to pipe for %s\n",
924
* set a new name for this channel
926
static void update_channel_name(struct capi_pvt *i)
928
char name[AST_CHANNEL_NAME];
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",
938
* send digits via INFO_REQ
940
static int capi_send_info_digits(struct capi_pvt *i, char *digits, int len)
942
MESSAGE_EXCHANGE_ERROR error;
947
memset(buf, 0, sizeof(buf));
949
INFO_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(), 0);
290
950
INFO_REQ_PLCI(&CMSG) = i->PLCI;
952
if (len > (sizeof(buf) - 2))
953
len = sizeof(buf) - 2;
294
INFO_REQ_CALLEDPARTYNUMBER(&CMSG) = buf;
957
for (a = 0; a < len; a++) {
958
buf[a + 2] = digits[a];
960
INFO_REQ_CALLEDPARTYNUMBER(&CMSG) = (_cstruct)buf;
297
962
if ((error = _capi_put_cmsg(&CMSG)) != 0) {
298
ast_log(LOG_ERROR,"error sending CALLEDPARTYNUMBER INFO (error=%#x)\n",error);
301
if (option_verbose > 5) {
302
ast_verbose(VERBOSE_PREFIX_4 "sent CALLEDPARTYNUMBER INFO digit = %c (PLCI=%#x)\n", digit, i->PLCI);
308
#ifndef FORCE_SOFTWARE_DTMF
309
ast_mutex_lock(&contrlock);
310
if ((capi_controllers[i->controller]->dtmf == 0) || (i->doDTMF == 1)) {
313
#ifndef FORCE_SOFTWARE_DTMF
314
ast_mutex_unlock(&contrlock);
317
#ifndef FORCE_SOFTWARE_DTMF
319
ast_mutex_unlock(&contrlock);
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;
329
buf[3] = AST_CAPI_DTMF_DURATION;
332
buf[5] = AST_CAPI_DTMF_DURATION;
338
FACILITY_REQ_FACILITYREQUESTPARAMETER(&CMSG) = buf;
965
cc_verbose(3, 1, VERBOSE_PREFIX_4 "%s: sent CALLEDPARTYNUMBER INFO digits = '%s' (PLCI=%#x)\n",
966
i->vname, buf + 2, i->PLCI);
973
static int pbx_capi_send_digit(struct ast_channel *c, char digit)
975
struct capi_pvt *i = CC_CHANNEL_PVT(c);
982
cc_log(LOG_ERROR, "No interface!\n");
986
memset(buf, 0, sizeof(buf));
988
cc_mutex_lock(&i->lock);
990
if ((c->_state == AST_STATE_DIALING) &&
991
(i->state != CAPI_STATE_DISCONNECTING)) {
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);
1000
/* if no SETUP-ACK yet, add it to the overlap list */
1001
strncat(i->overlapdigits, &digit, 1);
1004
cc_mutex_unlock(&i->lock);
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)) {
1012
cc_mutex_unlock(&i->lock);
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;
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);
1025
FACILITY_REQ_FACILITYREQUESTPARAMETER(&CMSG) = (_cstruct)buf;
340
if ((error = _capi_put_cmsg(&CMSG)) != 0) {
341
ast_log(LOG_ERROR,"error sending FACILITY_REQ (error=%#x)\n",error);
344
if (option_verbose > 4) {
345
ast_verbose(VERBOSE_PREFIX_3 "sent dtmf '%c'\n",digit);
349
#ifndef NEVER_EVER_EARLY_B3_CONNECTS
355
static int capi_alert(struct ast_channel *c) {
356
struct ast_capi_pvt *i = c->pvt->pvt;
357
MESSAGE_EXCHANGE_ERROR error;
360
ALERT_REQ_HEADER(&CMSG, ast_capi_ApplID, i->MessageNumber, 0);
361
ALERT_REQ_PLCI(&CMSG) = i->PLCI;
363
if ((error = _capi_put_cmsg(&CMSG)) != 0) {
364
ast_log(LOG_ERROR,"error sending ALERT_REQ PLCI = %#x\n",i->PLCI);
367
if (option_verbose > 5) {
368
ast_verbose(VERBOSE_PREFIX_4 "sent ALERT_REQ PLCI = %#x\n",i->PLCI);
372
i->state = CAPI_STATE_ALERTING;
376
#ifdef DEFLECT_ON_CIRCUITBUSY
377
static int capi_deflect(struct ast_channel *chan, void *data)
379
struct ast_capi_pvt *i = chan->pvt->pvt;
380
MESSAGE_EXCHANGE_ERROR Info;
388
ast_log(LOG_WARNING, "cd requires an argument (destination phone number)\n");
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");
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)) {
402
// make sure we hang up correctly
403
i->state = CAPI_STATE_CONNECTPENDING;
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
414
fac[9]=0x1A; // strlen destination + 15 = 26
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
438
fac[33]=0x01; // 0x1 = sending complete
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;
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);
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;
464
if ((Info = _capi_put_cmsg(&CMSG)) != 0) {
465
ast_log(LOG_ERROR,"Error sending INFO_REQ\n");
469
// ast_log(LOG_NOTICE,"%s\n",capi_cmsg2str(&CMSG));
470
ast_log(LOG_NOTICE,"sent INFO_REQ PLCI = %#x\n",i->PLCI);
478
void remove_pipe(int PLCI) {
479
struct capi_pipe *p,*ptmp;
481
ast_mutex_lock(&pipelock);
485
if (p->PLCI == PLCI) {
487
// mypipe == head of pipelist
489
if(p->fd > -1) close(p->fd);
490
if(p->i != NULL && p->i->fd > -1) close(p->i->fd);
492
if (option_verbose > 4) {
493
ast_verbose(VERBOSE_PREFIX_3 "removed pipe for PLCI = %#x\n",PLCI);
497
// somehwere inbetween or at the end
498
ptmp->next = p->next;
499
if (p->next == NULL) {
500
capi_last_plci = p->PLCI;
502
if(p->fd > -1) close(p->fd);
503
if(p->i != NULL && p->i->fd > -1) close(p->i->fd);
505
if (option_verbose > 4) {
506
ast_verbose(VERBOSE_PREFIX_3 "removed pipe for PLCI = %#x\n",PLCI);
514
ast_mutex_unlock(&pipelock);
517
static int capi_activehangup(struct ast_channel *c) {
518
struct ast_capi_pvt *i;
519
MESSAGE_EXCHANGE_ERROR error;
523
if (option_verbose > 2) {
525
ast_verbose(VERBOSE_PREFIX_4 "activehangingup\n");
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);
539
if (option_verbose > 5) {
540
ast_verbose(VERBOSE_PREFIX_4 "sent CONNECT_RESP for PLCI = %#x\n",i->PLCI);
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",
1032
cc_mutex_unlock(&i->lock);
1037
* send ALERT to ISDN line
1039
static int pbx_capi_alert(struct ast_channel *c)
1041
struct capi_pvt *i = CC_CHANNEL_PVT(c);
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);
1051
ALERT_REQ_HEADER(&CMSG, capi_ApplID, get_capi_MessageNumber(), 0);
1052
ALERT_REQ_PLCI(&CMSG) = i->PLCI;
1054
if (_capi_put_cmsg(&CMSG) != 0) {
1058
i->state = CAPI_STATE_ALERTING;
1059
ast_setstate(c, AST_STATE_RING);
1065
* cleanup the interface
1067
static void interface_cleanup(struct capi_pvt *i)
1072
cc_verbose(2, 1, VERBOSE_PREFIX_2 "%s: Interface cleanup PLCI=%#x\n",
1075
if (i->readerfd != -1) {
1079
if (i->writerfd != -1) {
1087
i->FaxState &= ~CAPI_FAX_STATE_MASK;
1090
i->MessageNumber = 0;
1094
memset(i->cid, 0, sizeof(i->cid));
1095
memset(i->dnid, 0, sizeof(i->dnid));
1100
ast_rtp_destroy(i->rtp);
1109
* disconnect b3 and wait for confirmation
1111
static void cc_disconnect_b3(struct capi_pvt *i, int wait)
1114
struct timespec abstime;
1116
if (!(i->isdnstate & (CAPI_ISDN_STATE_B3_UP | CAPI_ISDN_STATE_B3_PEND)))
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;
551
if ((error = _capi_put_cmsg(&CMSG)) != 0) {
552
ast_log(LOG_ERROR, "error sending DISCONNECT_B3_REQ NCCI=%#x\n",i->NCCI);
554
if (option_verbose > 5) {
555
ast_verbose(VERBOSE_PREFIX_4 "sent DISCONNECT_B3_REQ NCCI=%#x\n",i->NCCI);
558
// wait for the B3 layer to go down
559
while (i->state != CAPI_STATE_CONNECTED) {
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;
567
if ((error = _capi_put_cmsg(&CMSG)) != 0) {
568
ast_log(LOG_ERROR, "error sending DISCONNECT_REQ PLCI=%#x\n",i->PLCI);
570
if (option_verbose > 5) {
571
ast_verbose(VERBOSE_PREFIX_4 "sent DISCONNECT_REQ PLCI=%#x\n",i->PLCI);
574
// wait for the B1 layer to go down
575
while (i->state != CAPI_STATE_DISCONNECTED) {
582
static int capi_hangup(struct ast_channel *c) {
583
struct ast_capi_pvt *i;
586
// hmm....ok...this is called to free the capi interface (passive disconnect)
587
// or to bring down the channel (active disconnect)
589
if (option_verbose > 3)
590
ast_verbose(VERBOSE_PREFIX_3 "CAPI Hangingup\n");
593
ast_log(LOG_ERROR,"channel has no interface!\n");
598
if (i->state != CAPI_STATE_DISCONNECTED) {
600
capi_activehangup(c);
603
remove_pipe(i->PLCI);
606
if ((i->doDTMF == 1) && (i->vad != NULL)) {
607
ast_dsp_free(i->vad);
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));
613
ast_mutex_lock(&usecnt_lock);
1122
_capi_put_cmsg_wait_conf(i, &CMSG);
1125
cc_mutex_unlock(&i->lock);
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",
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",
1140
cc_verbose(4, 1, "%s: cond signal received for b3 down.\n",
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",
1153
* send CONNECT_B3_REQ
1155
static void cc_start_b3(struct capi_pvt *i)
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",
1173
static void start_early_b3(struct capi_pvt *i)
1175
if (i->doB3 != CAPI_B3_DONT) {
1176
/* we do early B3 Connect */
1182
* signal 'progress' to PBX
1184
static void send_progress(struct capi_pvt *i)
1186
struct ast_frame fr = { AST_FRAME_CONTROL, };
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);
1199
* hangup a line (CAPI messages)
1201
static void capi_activehangup(struct ast_channel *c, int state)
1203
struct capi_pvt *i = CC_CHANNEL_PVT(c);
1207
i->cause = c->hangupcause;
1208
if ((cause = pbx_builtin_getvar_helper(c, "PRI_CAUSE"))) {
1209
i->cause = atoi(cause);
1212
if ((i->isdnstate & CAPI_ISDN_STATE_ECT)) {
1213
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: activehangup ECT call\n",
1215
/* we do nothing, just wait for DISCONNECT_IND */
1219
cc_verbose(2, 1, VERBOSE_PREFIX_3 "%s: activehangingup (cause=%d) for PLCI=%#x\n",
1220
i->vname, i->cause, i->PLCI);
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);
1232
/* active disconnect */
1233
if ((i->isdnstate & CAPI_ISDN_STATE_B3_UP)) {
1234
cc_disconnect_b3(i, 0);
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);
1242
/* CONNECT_CONF not received yet? */
1243
capi_wait_conf(i, CAPI_CONNECT_CONF);
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);
1254
* PBX tells us to hangup a line
1256
static int pbx_capi_hangup(struct ast_channel *c)
1258
struct capi_pvt *i = CC_CHANNEL_PVT(c);
1263
* hmm....ok...this is called to free the capi interface (passive disconnect)
1264
* or to bring down the channel (active disconnect)
1268
cc_log(LOG_ERROR, "channel has no interface!\n");
1272
cc_mutex_lock(&i->lock);
1276
cc_verbose(3, 0, VERBOSE_PREFIX_2 "%s: CAPI Hangingup for PLCI=%#x in state %d\n",
1277
i->vname, i->PLCI, state);
1279
/* are we down, yet? */
1280
if (state != CAPI_STATE_DISCONNECTED) {
1282
i->state = CAPI_STATE_DISCONNECTING;
1287
ast_update_use_count();
1289
if ((i->doDTMF > 0) && (i->vad != NULL)) {
1290
ast_dsp_free(i->vad);
1295
/* disconnect already done, so cleanup */
1296
interface_cleanup(i);
1298
cc_mutex_unlock(&i->lock);
1301
/* not disconnected yet, we must actively do it */
1302
capi_activehangup(c, state);
1305
CC_CHANNEL_PVT(c) = NULL;
1306
ast_setstate(c, AST_STATE_DOWN);
1308
cc_mutex_lock(&usecnt_lock);
615
ast_mutex_unlock(&usecnt_lock);
616
ast_update_use_count();
620
ast_setstate(c,AST_STATE_DOWN);
624
static char *capi_number(char *data,int strip) {
625
unsigned len = *data;
627
// convert a capi struct to a \0 terminated string
628
if (!len || len < (unsigned int) strip) return NULL;
630
data = (char *)(data + 1 + strip);
631
return strndup((char *)data,len);
634
int capi_call(struct ast_channel *c, char *idest, int timeout)
636
struct ast_capi_pvt *i;
637
struct capi_pipe *p = NULL;
1310
cc_mutex_unlock(&usecnt_lock);
1318
static char *capi_number_func(unsigned char *data, unsigned int strip, char *buf)
1322
if (data[0] == 0xff) {
1323
len = read_capi_word(&data[1]);
1329
if (len > (AST_MAX_EXTENSION - 1))
1330
len = (AST_MAX_EXTENSION - 1);
1332
/* convert a capi struct to a \0 terminated string */
1333
if ((!len) || (len < strip))
1339
memcpy(buf, data, len);
1344
#define capi_number(data, strip) \
1345
capi_number_func(data, strip, alloca(AST_MAX_EXTENSION))
1348
* parse the dialstring
1350
static void parse_dialstring(char *buffer, char **interface, char **dest, char **param, char **ocid)
1353
char *buffer_p = buffer;
1356
/* interface is the first part of the string */
1357
*interface = buffer;
1364
if (*buffer_p == '/') {
1370
} else if (cp == 1) {
1374
cc_log(LOG_WARNING, "Too many parts in dialstring '%s'\n",
1381
if ((oc = strchr(*dest, ':')) != NULL) {
1386
cc_verbose(3, 1, VERBOSE_PREFIX_4 "parsed dialstring: '%s' '%s' '%s' '%s'\n",
1387
*interface, (*ocid) ? *ocid : "NULL", *dest, *param);
1392
* PBX tells us to make a call
1394
static int pbx_capi_call(struct ast_channel *c, char *idest, int timeout)
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];
1403
int callernplan = 0;
1404
int use_defaultcid = 0;
1405
const char *ton, *p;
1408
char callingsubaddress[AST_MAX_EXTENSION];
1409
char calledsubaddress[AST_MAX_EXTENSION];
645
1412
MESSAGE_EXCHANGE_ERROR error;
647
strncpy(buffer,(char *)idest,sizeof(buffer)-1);
648
msn = strtok(buffer, ":");
649
dest = strtok(NULL, ":");
653
ast_log(LOG_WARNING, "Destination %s requres a real destination\n", idest);
1414
cc_copy_string(buffer, idest, sizeof(buffer));
1415
parse_dialstring(buffer, &interface, &dest, ¶m, &ocid);
1417
/* init param settings */
1418
i->doB3 = CAPI_B3_DONT;
1420
memset(i->overlapdigits, 0, sizeof(i->overlapdigits));
1422
/* parse the parameters */
1423
while ((param) && (*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;
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;
1435
case 'o': /* overlap sending of digits */
1437
cc_log(LOG_WARNING, "Overlap already set in '%s'\n", idest);
1440
case 'd': /* use default cid */
1442
cc_log(LOG_WARNING, "Default CID already set in '%s'\n", idest);
1446
cc_log(LOG_WARNING, "Unknown parameter '%c' in '%s', ignoring.\n",
1451
if (((!dest) || (!dest[0])) && (i->doB3 != CAPI_B3_ALWAYS)) {
1452
cc_log(LOG_ERROR, "No destination or dialtone requested in '%s'\n", idest);
657
i->doB3 = AST_CAPI_B3_DONT; // <homer>DOH</homer>
660
if (((char *)dest)[0] == 'b') {
661
i->doB3 = AST_CAPI_B3_ALWAYS;
663
// only do B3 on successfull calls
664
if (((char *)dest)[0] == 'B') {
665
i->doB3 = AST_CAPI_B3_ON_SUCCESS;
668
if (i->doB3 != AST_CAPI_B3_DONT) {
672
if (option_verbose > 1) {
674
ast_verbose(VERBOSE_PREFIX_2 "CAPI Call %s %s", c->name, i->doB3?"with B3":"");
677
if (((char *)msn)[0] == '@') {
684
if (pipe(fds) == 0) {
685
ast_mutex_lock(&pipelock);
687
p = malloc(sizeof(struct capi_pipe));
688
memset(p, 0, sizeof(struct capi_pipe));
697
if (option_verbose > 4) {
698
ast_verbose(VERBOSE_PREFIX_3 "creating pipe for PLCI=-1\n");
700
ast_mutex_unlock(&pipelock);
704
i->MessageNumber = ast_capi_MessageNumber++;
705
CONNECT_REQ_HEADER(&CMSG, ast_capi_ApplID, i->MessageNumber, i->controller);
1456
CLIR = c->cid.cid_pres;
1457
callernplan = c->cid.cid_ton & 0x7f;
1459
if ((ton = pbx_builtin_getvar_helper(c, "CALLERTON"))) {
1460
callernplan = atoi(ton) & 0x7f;
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);
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;
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;
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",
1488
if ((i->doOverlap) && (strlen(dest))) {
1489
cc_copy_string(i->overlapdigits, dest, sizeof(i->overlapdigits));
1493
called[0] = strlen(dest) + 1;
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;
714
if (i->isdnmode && (strlen(msn)>strlen(i->msn)) && !strncmp(msn, i->msn, strlen(i->msn)))
715
msn += strlen(i->msn);
717
calling[0] = strlen(msn)+2;
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;
1500
if (c->cid.cid_num) {
1501
cc_copy_string(callerid, c->cid.cid_num, sizeof(callerid));
722
calling[2] = 0x80; // CLIP
724
strncpy(&calling[3],msn,sizeof(calling)-3);
725
CONNECT_REQ_CALLINGPARTYNUMBER(&CMSG) = calling;
726
CONNECT_REQ_CALLINGPARTYSUBADDRESS(&CMSG) = NULL;
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));
1506
if (use_defaultcid) {
1507
cc_copy_string(callerid, i->defaultcid, sizeof(callerid));
1509
cc_copy_string(callerid, ocid, sizeof(callerid));
1511
cc_copy_string(i->cid, callerid, sizeof(i->cid));
1513
calling[0] = strlen(callerid) + 2;
1514
calling[1] = callernplan;
1515
calling[2] = 0x80 | (CLIR & 0x63);
1516
strncpy(&calling[3], callerid, sizeof(calling) - 4);
1518
CONNECT_REQ_CALLINGPARTYNUMBER(&CMSG) = (_cstruct)calling;
1519
CONNECT_REQ_CALLINGPARTYSUBADDRESS(&CMSG) = (_cstruct)osa;
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;
732
1528
bchaninfo[0] = 2;
733
1529
bchaninfo[1] = 0x0;
734
1530
bchaninfo[2] = 0x0;
735
CONNECT_REQ_BCHANNELINFORMATION(&CMSG) = bchaninfo; // 0
737
if ((error = _capi_put_cmsg(&CMSG))) {
738
ast_log(LOG_ERROR,"error sending CONNECT_REQ (error=%#x)\n",error);
741
if (option_verbose > 5) {
742
ast_verbose(VERBOSE_PREFIX_4 "sent CONNECT_REQ MN =%#x\n",CMSG.Messagenumber);
1531
CONNECT_REQ_BCHANNELINFORMATION(&CMSG) = (_cstruct)bchaninfo; /* 0 */
1533
cc_mutex_lock(&i->lock);
1536
i->isdnstate |= CAPI_ISDN_STATE_PBX;
746
1537
i->state = CAPI_STATE_CONNECTPENDING;
748
1538
ast_setstate(c, AST_STATE_DIALING);
750
// XXX fixme, not nice:
751
/* if (i->controller > 0) {
752
capi_controllers[i->controller]->nfreebchannels--;
755
// now we shall return .... the rest has to be done by handle_msg
760
static int capi_answer(struct ast_channel *c) {
761
struct ast_capi_pvt *i = c->pvt->pvt;
762
MESSAGE_EXCHANGE_ERROR error;
764
char buf[AST_MAX_EXTENSION];
767
if (i->isdnmode && (strlen(i->incomingmsn)<strlen(i->dnid)))
768
dnid = i->dnid + strlen(i->incomingmsn);
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;
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;
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) {
791
if (option_verbose > 5) {
793
ast_verbose(VERBOSE_PREFIX_4 "sent CONNECT_RESP PLCI = %#x DNID = %s\n",i->PLCI,i->dnid);
797
i->state = CAPI_STATE_ANSWERING;
798
i->doB3 = AST_CAPI_B3_DONT;
805
struct ast_frame *capi_read(struct ast_channel *c)
807
struct ast_capi_pvt *i = c->pvt->pvt;
810
if ((i->state == CAPI_STATE_REMOTE_HANGUP)) {
811
ast_log(LOG_ERROR,"this channel is not connected\n");
814
if (i->state == CAPI_STATE_ONHOLD) {
815
i->fr.frametype = AST_FRAME_NULL;
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);
1546
cc_mutex_unlock(&i->lock);
1548
/* now we shall return .... the rest has to be done by handle_msg */
1553
* answer a capi call
1555
static int capi_send_answer(struct ast_channel *c, _cstruct b3conf)
1557
struct capi_pvt *i = CC_CHANNEL_PVT(c);
1559
char buf[CAPI_MAX_STRING];
1561
const char *connectednumber;
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);
1570
if ((connectednumber = pbx_builtin_getvar_helper(c, "CONNECTEDNUMBER"))) {
1571
dnid = connectednumber;
1574
CONNECT_RESP_HEADER(&CMSG, capi_ApplID, i->MessageNumber, 0);
1575
CONNECT_RESP_PLCI(&CMSG) = i->PLCI;
1576
CONNECT_RESP_REJECT(&CMSG) = 0;
1578
buf[0] = strlen(dnid) + 2;
1581
strncpy(&buf[3], dnid, sizeof(buf) - 4);
1582
CONNECT_RESP_CONNECTEDNUMBER(&CMSG) = (_cstruct)buf;
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;
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);
1596
cc_verbose(3, 0, VERBOSE_PREFIX_2 "%s: Answering for %s\n",
1599
if (_capi_put_cmsg(&CMSG) != 0) {
1603
i->state = CAPI_STATE_ANSWERING;
1604
i->doB3 = CAPI_B3_DONT;
1611
* PBX tells us to answer a call
1613
static int pbx_capi_answer(struct ast_channel *c)
1615
struct capi_pvt *i = CC_CHANNEL_PVT(c);
1618
i->bproto = CC_BPROTO_TRANSPARENT;
1621
if (!tcap_is_digital(c->transfercapability))
1622
i->bproto = CC_BPROTO_RTP;
1625
ret = capi_send_answer(c, NULL);
1630
* read for a channel
1632
static struct ast_frame *pbx_capi_read(struct ast_channel *c)
1634
struct capi_pvt *i = CC_CHANNEL_PVT(c);
1635
struct ast_frame *f;
819
1638
if (i == NULL) {
820
ast_log(LOG_ERROR,"channel has no interface\n");
823
i->fr.frametype = AST_FRAME_NULL;
826
i->fr.delivery.tv_sec = 0;
827
i->fr.delivery.tv_usec = 0;
829
readsize = read(i->fd,&i->fr,sizeof(struct ast_frame));
1639
cc_log(LOG_ERROR, "channel has no interface\n");
1642
if (i->readerfd == -1) {
1643
cc_log(LOG_ERROR, "no readerfd\n");
1648
f->frametype = AST_FRAME_NULL;
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");
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");
840
if (i->fr.frametype == AST_FRAME_NULL) {
1653
cc_log(LOG_ERROR, "did not read a whole frame\n");
1659
if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP)) {
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);
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");
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);
846
int capi_write(struct ast_channel *c, struct ast_frame *f)
1682
* PBX tells us to write for a channel
1684
static int pbx_capi_write(struct ast_channel *c, struct ast_frame *f)
848
struct ast_capi_pvt *i = c->pvt->pvt;
1686
struct capi_pvt *i = CC_CHANNEL_PVT(c);
1687
MESSAGE_EXCHANGE_ERROR error;
850
MESSAGE_EXCHANGE_ERROR error;
853
1691
struct ast_frame *fsmooth;
858
#ifndef NEVER_EVER_EARLY_B3_CONNECTS
859
// dont send audio to the local exchange!
860
if (i->earlyB3 == 1 || !i->NCCI) {
866
ast_log(LOG_ERROR,"channel has no interface\n");
1696
cc_log(LOG_ERROR, "channel has no interface\n");
1700
if ((!(i->isdnstate & CAPI_ISDN_STATE_B3_UP)) || (!i->NCCI) ||
1701
((i->isdnstate & (CAPI_ISDN_STATE_B3_CHANGE | CAPI_ISDN_STATE_LI)))) {
1705
if ((!(i->ntmode)) && (i->state != CAPI_STATE_CONNECTED)) {
870
1709
if (f->frametype == AST_FRAME_NULL) {
873
1712
if (f->frametype == AST_FRAME_DTMF) {
874
ast_log(LOG_ERROR,"dtmf frame should be written\n");
1713
cc_log(LOG_ERROR, "dtmf frame should be written\n");
877
1716
if (f->frametype != AST_FRAME_VOICE) {
878
ast_log(LOG_ERROR,"not a voice frame\n");
881
if (f->subclass != capi_capability) {
882
ast_log(LOG_ERROR,"dont know how to write subclass %d\n",f->subclass);
885
// ast_log(LOG_NOTICE,"writing frame %d %d\n",f->frametype,f->subclass);
887
if (ast_smoother_feed(i->smoother, f)!=0) {
888
ast_log(LOG_ERROR,"failed to fill smoother\n");
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;
899
if (ast_mutex_lock(&capi_send_buffer_lock)) {
900
ast_log(LOG_WARNING,"Unable to lock B3 send buffer!\n");
905
for (j=0;j<fsmooth->datalen;j++) {
906
buf[j] = i->g.txgains[reversebits[((unsigned char *)fsmooth->data)[j]]];
909
for (j=0;j<fsmooth->datalen;j++) {
910
buf[j] = reversebits[ ((unsigned char *)fsmooth->data)[j] ];
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]]) );
920
for(j=0;j<ECHO_TX_COUNT-1;j++) {
921
i->txavg[j] = i->txavg[j+1];
923
i->txavg[ECHO_TX_COUNT-1] = txavg;
925
// ast_log(LOG_NOTICE,"txavg = %d\n",txavg);
928
for (j=0;j<fsmooth->datalen;j++) {
929
buf[j] = i->g.txgains[reversebits[((unsigned char *)fsmooth->data)[j]]];
932
for (j=0;j<fsmooth->datalen;j++) {
933
buf[j] = reversebits[ ((unsigned char *)fsmooth->data)[j] ];
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++;
944
if (ast_mutex_unlock(&capi_send_buffer_lock)) {
945
ast_log(LOG_WARNING,"Unable to unlock B3 send buffer!\n");
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);
958
if (option_verbose > 5) {
960
ast_verbose(VERBOSE_PREFIX_4 "sent DATA_B3_REQ (NCCI=%#x) (%d bytes)\n",i->NCCI,fsmooth->datalen);
965
if (i->B3in > 0) i->B3in--;
966
ast_mutex_unlock(&i->lockB3in);
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);
973
if (option_verbose > 5) {
975
ast_verbose(VERBOSE_PREFIX_4 "sent DATA_B3_REQ (NCCI=%#x) (%d bytes)\n",i->NCCI,fsmooth->datalen);
980
// ast_frfree(fsmooth);
982
fsmooth=ast_smoother_read(i->smoother);
987
static int capi_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
989
struct ast_capi_pvt *p = newchan->pvt->pvt;
994
int capi_indicate(struct ast_channel *c,int condition) {
998
int capi_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc) {
1003
struct ast_channel *capi_new(struct ast_capi_pvt *i,int state) {
1004
struct ast_channel *tmp;
1007
tmp = ast_channel_alloc(1);
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++);
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");
1019
i->fr.frametype = 0;
1022
i->fr.delivery.tv_sec = 0;
1023
i->fr.delivery.tv_usec = 0;
1717
cc_log(LOG_ERROR,"not a voice frame\n");
1720
if (i->FaxState & CAPI_FAX_STATE_ACTIVE) {
1721
cc_verbose(3, 1, VERBOSE_PREFIX_2 "%s: write on fax activity?\n",
1725
if ((!f->data) || (!f->datalen)) {
1726
cc_log(LOG_DEBUG, "No data for FRAME_VOICE %s\n", c->name);
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);
1736
return capi_write_rtp(c, f);
1739
if ((!i->smoother) || (ast_smoother_feed(i->smoother, f) != 0)) {
1740
cc_log(LOG_ERROR, "%s: failed to fill smoother\n", i->vname);
1744
for (fsmooth = ast_smoother_read(i->smoother);
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;
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++;
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]]] );
1764
txavg += abs( capiALAW2INT[reversebits[ ((unsigned char*)fsmooth->data)[j]]] );
1768
for(j = 0; j < ECHO_TX_COUNT - 1; j++) {
1769
i->txavg[j] = i->txavg[j+1];
1771
i->txavg[ECHO_TX_COUNT - 1] = txavg;
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]];
1778
for (j = 0; j < fsmooth->datalen; j++) {
1779
buf[j] = i->g.txgains[reversebits[((unsigned char *)fsmooth->data)[j]]];
1786
error = _capi_put_cmsg(&CMSG);
1788
cc_verbose(3, 1, VERBOSE_PREFIX_4 "%s: too much voice to send for NCCI=%#x\n",
1793
cc_mutex_lock(&i->lock);
1794
i->B3q -= fsmooth->datalen;
1797
cc_mutex_unlock(&i->lock);
1804
* new channel (masq)
1806
static int pbx_capi_fixup(struct ast_channel *oldchan, struct ast_channel *newchan)
1808
struct capi_pvt *i = CC_CHANNEL_PVT(newchan);
1810
cc_verbose(3, 1, VERBOSE_PREFIX_2 "%s: %s fixup now %s\n",
1811
i->vname, oldchan->name, newchan->name);
1813
cc_mutex_lock(&i->lock);
1815
cc_mutex_unlock(&i->lock);
1820
* activate (another B protocol)
1822
static void cc_select_b(struct capi_pvt *i, _cstruct b3conf)
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;
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);
1840
_capi_put_cmsg(&CMSG);
1844
* do line initerconnect
1846
static int line_interconnect(struct capi_pvt *i0, struct capi_pvt *i1, int start)
1851
if ((i0->isdnstate & CAPI_ISDN_STATE_DISCONNECT) ||
1852
(i1->isdnstate & CAPI_ISDN_STATE_DISCONNECT))
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);
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;
1868
memset(buf, 0, sizeof(buf));
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 */
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);
1888
FACILITY_REQ_FACILITYREQUESTPARAMETER(&CMSG) = (_cstruct)buf;
1890
_capi_put_cmsg(&CMSG);
1893
i0->isdnstate |= CAPI_ISDN_STATE_LI;
1894
i1->isdnstate |= CAPI_ISDN_STATE_LI;
1896
i0->isdnstate &= ~CAPI_ISDN_STATE_LI;
1897
i1->isdnstate &= ~CAPI_ISDN_STATE_LI;
1904
* disconnect b3 and bring it up with another protocol
1906
static void cc_switch_b_protocol(struct capi_pvt *i)
1908
int waitcount = 200;
1910
cc_disconnect_b3(i, 1);
1912
i->isdnstate |= CAPI_ISDN_STATE_B3_CHANGE;
1913
cc_select_b(i, NULL);
1916
/* on outgoing call we must do the connect-b3 request */
1920
/* wait for the B3 layer to come up */
1921
while ((waitcount > 0) &&
1922
(!(i->isdnstate & CAPI_ISDN_STATE_B3_UP))) {
1926
if (!(i->isdnstate & CAPI_ISDN_STATE_B3_UP)) {
1927
cc_log(LOG_ERROR, "capi switch b3: no b3 up\n");
1932
* set the b3 protocol to transparent
1934
static int cc_set_transparent(struct capi_pvt *i)
1936
if (i->bproto != CC_BPROTO_RTP) {
1941
i->bproto = CC_BPROTO_TRANSPARENT;
1942
cc_switch_b_protocol(i);
1948
* set the b3 protocol to RTP (if wanted)
1950
static void cc_unset_transparent(struct capi_pvt *i, int rtpwanted)
1953
(i->isdnstate & CAPI_ISDN_STATE_DISCONNECT))
1956
i->bproto = CC_BPROTO_RTP;
1957
cc_switch_b_protocol(i);
1964
* native bridging / line interconnect
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,
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;
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);
1979
if ((!i0->bridge) || (!i1->bridge))
1980
return AST_BRIDGE_FAILED_NOWARN;
1982
if ((!capi_controllers[i0->controller]->lineinterconnect) ||
1983
(!capi_controllers[i1->controller]->lineinterconnect)) {
1984
return AST_BRIDGE_FAILED_NOWARN;
1987
if ((i0->isdnstate & CAPI_ISDN_STATE_ECT) ||
1988
(i0->isdnstate & CAPI_ISDN_STATE_ECT)) {
1989
return AST_BRIDGE_FAILED;
1992
capi_wait_for_b3_up(i0);
1993
capi_wait_for_b3_up(i1);
1995
if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0))
1996
capi_detect_dtmf(i0->owner, 0);
1998
if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1))
1999
capi_detect_dtmf(i1->owner, 0);
2001
capi_echo_canceller(i0->owner, EC_FUNCTION_DISABLE);
2002
capi_echo_canceller(i1->owner, EC_FUNCTION_DISABLE);
2004
if (line_interconnect(i0, i1, 1)) {
2005
ret = AST_BRIDGE_FAILED;
2006
goto return_from_bridge;
2010
struct ast_channel *c0_priority[2] = {c0, c1};
2011
struct ast_channel *c1_priority[2] = {c1, c0};
2013
struct ast_frame *f;
2014
struct ast_channel *who;
2016
who = ast_waitfor_n(priority ? c0_priority : c1_priority, 2, &timeoutms);
2019
ret = AST_BRIDGE_RETRY;
2025
if (!f || (f->frametype == AST_FRAME_CONTROL)
2026
|| (f->frametype == AST_FRAME_DTMF)) {
2029
ret = AST_BRIDGE_COMPLETE;
2039
/* Swap who gets priority */
2040
priority = !priority;
2043
line_interconnect(i0, i1, 0);
2047
if (!(flags & AST_BRIDGE_DTMF_CHANNEL_0))
2048
capi_detect_dtmf(i0->owner, 1);
2050
if (!(flags & AST_BRIDGE_DTMF_CHANNEL_1))
2051
capi_detect_dtmf(i1->owner, 1);
2053
capi_echo_canceller(i0->owner, EC_FUNCTION_ENABLE);
2054
capi_echo_canceller(i1->owner, EC_FUNCTION_ENABLE);
2060
* a new channel is needed
2062
static struct ast_channel *capi_new(struct capi_pvt *i, int state)
2064
struct ast_channel *tmp;
2069
tmp = ast_channel_alloc(0);
2072
cc_log(LOG_ERROR,"Unable to allocate channel!\n");
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++);
2080
snprintf(tmp->name, sizeof(tmp->name) - 1, "CAPI/%s/%s-%x",
2081
i->name, i->dnid, capi_counter++);
2083
tmp->type = channeltype;
2085
if (pipe(fds) != 0) {
2086
cc_log(LOG_ERROR, "%s: unable to create pipe.\n",
2088
ast_channel_free(tmp);
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);
2098
tmp->fds[0] = i->readerfd;
2100
if (i->smoother != NULL) {
2101
ast_smoother_reset(i->smoother, CAPI_MAX_B3_BLOCK_SIZE);
1025
2104
i->state = CAPI_STATE_DISCONNECTED;
1027
i->calledPartyIsISDN = 0; // let's be pessimistic
1029
i->doB3 = AST_CAPI_B3_DONT;
2105
i->calledPartyIsISDN = 1;
2106
i->doB3 = CAPI_B3_DONT;
1030
2108
i->outgoing = 0;
1031
2109
i->onholdPLCI = 0;
1034
ast_mutex_init(&i->lockB3in);
1037
memset(i->txavg,0,ECHO_TX_COUNT);
2110
i->doholdtype = i->holdtype;
2112
memset(i->txavg, 0, ECHO_TX_COUNT);
1040
#ifndef FORCE_SOFTWARE_DTMF
1041
if (i->doDTMF == 1) {
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
1049
if (tmp->pvt == 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);
2122
CC_CHANNEL_PVT(tmp) = i;
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 */
2133
/* start with rtp */
2134
tmp->nativeformats = i->rtpcodec;
2135
i->bproto = CC_BPROTO_RTP;
1066
2138
fmt = ast_best_codec(tmp->nativeformats);
1067
// fmt = capi_capability;
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);
2143
tmp->tech = &capi_tech;
2144
tmp->rawreadformat = fmt;
2145
tmp->rawwriteformat = fmt;
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));
2154
if (!ast_strlen_zero(i->cid)) {
2155
if (tmp->cid.cid_num) {
2156
free(tmp->cid.cid_num);
2158
tmp->cid.cid_num = strdup(i->cid);
2160
if (!ast_strlen_zero(i->dnid)) {
2161
if (tmp->cid.cid_dnid) {
2162
free(tmp->cid.cid_dnid);
2164
tmp->cid.cid_dnid = strdup(i->dnid);
2166
tmp->cid.cid_ton = i->cid_ton;
2168
tmp->amaflags = i->amaflags;
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);
2175
cc_copy_string(tmp->accountcode, i->accountcode, sizeof(tmp->accountcode));
2176
cc_copy_string(tmp->language, i->language, sizeof(tmp->language));
1077
2178
i->owner = tmp;
1078
ast_mutex_lock(&usecnt_lock);
2179
cc_mutex_lock(&usecnt_lock);
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)
1086
if (ast_pbx_start(tmp)) {
1087
ast_log(LOG_ERROR,"Unable to start pbx on channel!\n");
1091
if (option_verbose > 2) {
1092
ast_verbose(VERBOSE_PREFIX_3 "started pbx on channel (callgroup=%d)!\n",tmp->callgroup);
1097
ast_log(LOG_ERROR,"Unable to allocate channel!\n");
2184
ast_setstate(tmp, state);
1103
struct ast_channel *capi_request(char *type, int format, void *data)
2190
* PBX wants us to dial ...
2192
static struct ast_channel *
2193
pbx_capi_request(const char *type, int format, void *data, int *cause)
1105
struct ast_capi_pvt *i;
1106
2196
struct ast_channel *tmp = NULL;
1107
char *dest,*omsn,*msn;
1108
char buffer[AST_MAX_EXTENSION];
1110
char *stringp,tmpstr[AST_MAX_EXTENSION];
1112
if (option_verbose > 1) {
1114
ast_verbose(VERBOSE_PREFIX_3 "data = %s\n",(char *)data);
1116
strncpy(buffer,(char *)data,sizeof(buffer)-1);
1118
omsn = strtok(buffer, ":");
1119
dest = strtok(NULL, ":");
1121
if (option_verbose > 1) {
1123
ast_verbose(VERBOSE_PREFIX_3 "capi request omsn = %s\n",omsn);
1126
if (((char *)omsn)[0] == '@') {
1130
ast_mutex_lock(&iflock);
1133
strncpy(tmpstr,i->msn,sizeof(tmpstr)-1);
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)))) {
1141
if (option_verbose > 1) {
1143
ast_verbose(VERBOSE_PREFIX_2 "found capi with omsn = %s\n",omsn);
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) {
1151
strncpy(i->dnid,omsn,sizeof(i->dnid)-1);
1152
tmp = capi_new(i, AST_STATE_DOWN);
1155
i->outgoing = 1; // this is an outgoing line
1157
// capi_detect_dtmf(tmp,1);
1158
ast_mutex_unlock(&contrlock);
1159
ast_mutex_unlock(&iflock);
1164
ast_mutex_unlock(&contrlock);
1165
ast_log(LOG_ERROR,"no free b channel on controllers (map=%#x)\n",(int) i->controllers);
1168
msn = strsep(&stringp,",");
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);
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);
1183
if ((p == NULL) && (capi_last_plci != PLCI)){
1185
ast_log(LOG_NOTICE,"PLCI doesnt match last pipe (PLCI = %#x)\n",PLCI);
1187
ast_mutex_unlock(&pipelock);
1191
if ((p->PLCI == PLCI) || ( (p->PLCI == -1) && (p->i->MessageNumber == MN) ) ){
1192
ast_mutex_unlock(&pipelock);
1198
ast_log(LOG_ERROR,"unable to find a pipe for PLCI = %#x MN = %#x\n",PLCI,MN);
1200
ast_mutex_unlock(&pipelock);
1204
int pipe_frame(struct capi_pipe *p,struct ast_frame *f) {
1209
FD_SET(p->fd,&wfds);
1212
if ((f->frametype == AST_FRAME_VOICE) && (p->i->doDTMF == 1) && (p->i->vad != NULL)) {
1214
f = ast_dsp_process(p->c,p->i->vad,f);
1216
f = ast_dsp_process(p->c,p->i->vad,f, 0);
1218
if (f->frametype == AST_FRAME_NULL) {
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));
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);
2197
char *dest, *interface, *param, *ocid;
2198
char buffer[CAPI_MAX_STRING];
2199
ast_group_t capigroup = 0;
2200
unsigned int controller = 0;
2203
cc_verbose(1, 1, VERBOSE_PREFIX_4 "data = %s format=%d\n", (char *)data, format);
2205
cc_copy_string(buffer, (char *)data, sizeof(buffer));
2206
parse_dialstring(buffer, &interface, &dest, ¶m, &ocid);
2208
if ((!interface) || (!dest)) {
2209
cc_log(LOG_ERROR, "Syntax error in dialstring. Read the docs!\n");
2210
*cause = AST_CAUSE_INVALID_NUMBER_FORMAT;
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",
2223
cc_verbose(1, 1, VERBOSE_PREFIX_4 "capi request for interface '%s'\n",
2227
cc_mutex_lock(&iflock);
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 */
2234
/* unused channel */
2236
/* DIAL(CAPI/contrX/...) */
2237
if (i->controller != controller) {
2238
/* keep on running! */
2242
/* DIAL(CAPI/gX/...) */
2243
if ((interface[0] == 'g') && (!(i->group & capigroup))) {
2244
/* keep on running! */
2247
/* DIAL(CAPI/<interface-name>/...) */
2248
if ((interface[0] != 'g') && (strcmp(interface, i->name))) {
2249
/* keep on running! */
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);
2257
cc_log(LOG_ERROR, "cannot create new capi channel\n");
2258
interface_cleanup(i);
2261
i->outgoing = 1; /* this is an outgoing line */
2262
cc_mutex_unlock(&iflock);
2265
cc_mutex_unlock(&iflock);
2266
cc_verbose(2, 0, VERBOSE_PREFIX_3 "didn't find capi device for interface '%s'\n",
2268
*cause = AST_CAUSE_REQUESTED_CHAN_UNAVAIL;
2273
* fill out fax conf struct
2275
static void setup_b3_fax_config(B3_PROTO_FAXG3 *b3conf, int fax_format, char *stationid, char *headline)
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);
2295
* change b protocol to fax
2297
static void capi_change_bchan_fax(struct ast_channel *c, B3_PROTO_FAXG3 *b3conf)
2299
struct capi_pvt *i = CC_CHANNEL_PVT(c);
2301
i->isdnstate |= CAPI_ISDN_STATE_B3_SELECT;
2302
cc_disconnect_b3(i, 1);
2303
cc_select_b(i, (_cstruct)b3conf);
2308
* capicommand 'receivefax'
2310
static int pbx_capi_receive_fax(struct ast_channel *c, char *data)
2312
struct capi_pvt *i = CC_CHANNEL_PVT(c);
2314
char *filename, *stationid, *headline;
2315
B3_PROTO_FAXG3 b3conf;
2316
char buffer[CAPI_MAX_STRING];
2318
if (!data) { /* no data implies no filename or anything is present */
2319
cc_log(LOG_WARNING, "capi receivefax requires a filename\n");
2323
filename = strsep(&data, "|");
2324
stationid = strsep(&data, "|");
2328
stationid = emptyid;
2332
capi_wait_for_answered(i);
2334
if ((i->fFax = fopen(filename, "wb")) == NULL) {
2335
cc_log(LOG_WARNING, "can't create fax output file (%s)\n", strerror(errno));
2339
i->FaxState |= CAPI_FAX_STATE_ACTIVE;
2340
setup_b3_fax_config(&b3conf, FAX_SFF_FORMAT, stationid, headline);
2342
i->bproto = CC_BPROTO_FAXG3;
2345
case CAPI_STATE_ALERTING:
2346
case CAPI_STATE_DID:
2347
case CAPI_STATE_INCALL:
2348
capi_send_answer(c, (_cstruct)&b3conf);
2350
case CAPI_STATE_CONNECTED:
2351
capi_change_bchan_fax(c, &b3conf);
2354
i->FaxState &= ~CAPI_FAX_STATE_ACTIVE;
2355
cc_log(LOG_WARNING, "capi receive fax in wrong state (%d)\n",
2359
capi_wait_for_fax_finish(i);
2361
res = (i->FaxState & CAPI_FAX_STATE_ERROR) ? 1 : 0;
2362
i->FaxState &= ~(CAPI_FAX_STATE_ACTIVE | CAPI_FAX_STATE_ERROR);
2364
/* if the file has zero length */
2365
if (ftell(i->fFax) == 0L) {
2369
cc_verbose(2, 1, VERBOSE_PREFIX_3 "Closing fax file...\n");
2375
VERBOSE_PREFIX_1 "capi receivefax: fax receive failed reason=0x%04x reasonB3=0x%04x\n",
2376
i->reason, i->reasonb3);
2380
VERBOSE_PREFIX_1 "capi receivefax: fax receive successful.\n");
2382
snprintf(buffer, CAPI_MAX_STRING-1, "%d", res);
2383
pbx_builtin_setvar_helper(c, "FAXSTATUS", buffer);
2389
* capicommand 'sendfax'
2391
static int pbx_capi_send_fax(struct ast_channel *c, char *data)
2393
struct capi_pvt *i = CC_CHANNEL_PVT(c);
2395
char *filename, *stationid, *headline;
2396
B3_PROTO_FAXG3 b3conf;
2397
char buffer[CAPI_MAX_STRING];
2399
if (!data) { /* no data implies no filename or anything is present */
2400
cc_log(LOG_WARNING, "capi sendfax requires a filename\n");
2404
filename = strsep(&data, "|");
2405
stationid = strsep(&data, "|");
2409
stationid = emptyid;
2413
capi_wait_for_answered(i);
2415
if ((i->fFax = fopen(filename, "rb")) == NULL) {
2416
cc_log(LOG_WARNING, "can't open fax file (%s)\n", strerror(errno));
2420
i->FaxState |= (CAPI_FAX_STATE_ACTIVE | CAPI_FAX_STATE_SENDMODE);
2421
setup_b3_fax_config(&b3conf, FAX_SFF_FORMAT, stationid, headline);
2423
i->bproto = CC_BPROTO_FAXG3;
2426
case CAPI_STATE_ALERTING:
2427
case CAPI_STATE_DID:
2428
case CAPI_STATE_INCALL:
2429
capi_send_answer(c, (_cstruct)&b3conf);
2431
case CAPI_STATE_CONNECTED:
2432
capi_change_bchan_fax(c, &b3conf);
2435
i->FaxState &= ~CAPI_FAX_STATE_ACTIVE;
2436
cc_log(LOG_WARNING, "capi send fax in wrong state (%d)\n",
2440
capi_wait_for_fax_finish(i);
2442
res = (i->FaxState & CAPI_FAX_STATE_ERROR) ? 1 : 0;
2443
i->FaxState &= ~(CAPI_FAX_STATE_ACTIVE | CAPI_FAX_STATE_ERROR);
2445
/* if the file has zero length */
2446
if (ftell(i->fFax) == 0L) {
2450
cc_verbose(2, 1, VERBOSE_PREFIX_3 "Closing fax file...\n");
2456
VERBOSE_PREFIX_1 "capi sendfax: fax send failed reason=0x%04x reasonB3=0x%04x\n",
2457
i->reason, i->reasonb3);
2460
VERBOSE_PREFIX_1 "capi sendfax: fax sent successful.\n");
2462
snprintf(buffer, CAPI_MAX_STRING-1, "%d", res);
2463
pbx_builtin_setvar_helper(c, "FAXSTATUS", buffer);
2469
* Fax guard tone -- Handle and return NULL
2471
static void capi_handle_dtmf_fax(struct capi_pvt *i)
2473
struct ast_channel *c = i->owner;
2476
cc_log(LOG_ERROR, "No channel!\n");
2480
if (i->FaxState & CAPI_FAX_STATE_HANDLED) {
2481
cc_log(LOG_DEBUG, "Fax already handled\n");
2484
i->FaxState |= CAPI_FAX_STATE_HANDLED;
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",
2493
if (!strcmp(c->exten, "fax")) {
2494
cc_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n");
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);
2503
cc_verbose(2, 0, VERBOSE_PREFIX_3 "%s: Redirecting %s to fax extension\n",
2506
/* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
2507
pbx_builtin_setvar_helper(c, "FAXEXTEN", c->exten);
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);
2515
* find the interface (pvt) the PLCI belongs to
2517
static struct capi_pvt *find_interface_by_plci(unsigned int plci)
2524
cc_mutex_lock(&iflock);
2525
for (i = iflist; i; i = i->next) {
2526
if (i->PLCI == plci)
2529
cc_mutex_unlock(&iflock);
2535
* find the interface (pvt) the messagenumber belongs to
2537
static struct capi_pvt *find_interface_by_msgnum(unsigned short msgnum)
2541
if (msgnum == 0x0000)
2544
cc_mutex_lock(&iflock);
2545
for (i = iflist; i; i = i->next) {
2546
if ((i->PLCI == 0) && (i->MessageNumber == msgnum))
2549
cc_mutex_unlock(&iflock);
2555
* see if did matches
1242
2557
static int search_did(struct ast_channel *c)
1247
// 1 = possible match
1248
struct ast_capi_pvt *i = c->pvt->pvt;
2563
* 1 = possible match
2565
struct capi_pvt *i = CC_CHANNEL_PVT(c);
1251
if (strlen(i->dnid)<strlen(i->incomingmsn))
2568
if (!strlen(i->dnid) && (i->immediate)) {
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);
2573
if (strlen(i->dnid) < strlen(i->incomingmsn))
2578
if (ast_exists_extension(NULL, c->context, exten, 1, i->cid)) {
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);
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);
1254
// exten = i->dnid + strlen(i->incomingmsn);
1257
if (ast_exists_extension(NULL, c->context, exten, 1, NULL)) {
1259
strncpy(c->exten, exten, sizeof(c->exten) - 1);
1263
if (ast_canmatch_extension(NULL, c->context, exten, 1, NULL)) {
1271
int pipe_msg(int PLCI,_cmsg *CMSG) {
1272
struct capi_pipe *p;
1274
MESSAGE_EXCHANGE_ERROR error;
1275
struct ast_frame fr;
2596
* Progress Indicator
2598
static void handle_progress_indicator(_cmsg *CMSG, unsigned int PLCI, struct capi_pvt *i)
2600
if (INFO_IND_INFOELEMENT(CMSG)[0] < 2) {
2601
cc_verbose(3, 1, VERBOSE_PREFIX_4 "%s: Progress description missing\n",
2606
switch(INFO_IND_INFOELEMENT(CMSG)[2] & 0x7f) {
2608
cc_verbose(4, 1, VERBOSE_PREFIX_4 "%s: Not end-to-end ISDN\n",
2612
cc_verbose(4, 1, VERBOSE_PREFIX_4 "%s: Destination is non ISDN\n",
2614
i->calledPartyIsISDN = 0;
2617
cc_verbose(4, 1, VERBOSE_PREFIX_4 "%s: Origination is non ISDN\n",
2621
cc_verbose(4, 1, VERBOSE_PREFIX_4 "%s: Call returned to ISDN\n",
2625
cc_verbose(4, 1, VERBOSE_PREFIX_4 "%s: Interworking occured\n",
2629
cc_verbose(4, 1, VERBOSE_PREFIX_4 "%s: In-band information available\n",
2633
cc_verbose(3, 1, VERBOSE_PREFIX_4 "%s: Unknown progress description %02x\n",
2634
i->vname, INFO_IND_INFOELEMENT(CMSG)[2]);
2641
* if the dnid matches, start the pbx
2643
static void start_pbx_on_match(struct capi_pvt *i, unsigned int PLCI, _cword MessageNumber)
2645
struct ast_channel *c;
2650
if ((i->isdnstate & CAPI_ISDN_STATE_PBX_DONT)) {
2651
/* we already found non-match here */
2654
if ((i->isdnstate & CAPI_ISDN_STATE_PBX)) {
2655
cc_verbose(3, 1, VERBOSE_PREFIX_2 "%s: pbx already started on channel %s\n",
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",
2665
cc_copy_string(c->exten, i->dnid, sizeof(c->exten));
2667
capi_channel_task(c, CAPI_CHANNEL_TASK_PICKUP);
2671
switch(search_did(i->owner)) {
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",
2678
capi_channel_task(c, CAPI_CHANNEL_TASK_HANGUP);
2680
cc_verbose(2, 1, VERBOSE_PREFIX_2 "Started pbx on channel %s\n",
2685
/* would possibly match */
2686
if (i->isdnmode == CAPI_ISDNMODE_DID)
2688
/* fall through for MSN mode, because there won't be a longer msn */
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",
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);
2704
* Called Party Number via INFO_IND
2706
static void capidev_handle_did_digits(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt *i)
2709
struct ast_frame fr = { AST_FRAME_NULL, };
2713
cc_log(LOG_ERROR, "No channel for interface!\n");
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",
2723
did = capi_number(INFO_IND_INFOELEMENT(CMSG), 1);
2725
if ((!(i->isdnstate & CAPI_ISDN_STATE_DID)) &&
2726
(strlen(i->dnid) && !strcasecmp(i->dnid, did))) {
2730
if ((did) && (strlen(i->dnid) < (sizeof(i->dnid) - 1)))
2731
strcat(i->dnid, did);
2733
i->isdnstate |= CAPI_ISDN_STATE_DID;
2735
update_channel_name(i);
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);
2747
start_pbx_on_match(i, PLCI, HEADER_MSGNUM(CMSG));
2752
* send control according to cause code
2754
static void queue_cause_control(struct capi_pvt *i, int control)
2756
struct ast_frame fr = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP, };
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)) {
2765
fr.subclass = AST_CONTROL_BUSY;
2768
local_queue_frame(i, &fr);
2773
* Disconnect via INFO_IND
2775
static void capidev_handle_info_disconnect(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt *i)
2779
i->isdnstate |= CAPI_ISDN_STATE_DISCONNECT;
2781
if ((i->isdnstate & CAPI_ISDN_STATE_ECT)) {
2782
cc_verbose(4, 1, VERBOSE_PREFIX_3 "%s: Disconnect ECT call\n",
2784
/* we do nothing, just wait for DISCONNECT_IND */
2788
if (PLCI == i->onholdPLCI) {
2789
cc_verbose(4, 1, VERBOSE_PREFIX_3 "%s: Disconnect onhold call\n",
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);
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",
2803
if (i->state == CAPI_STATE_CONNECTED)
2804
queue_cause_control(i, 0);
2806
queue_cause_control(i, 1);
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",
2815
queue_cause_control(i, 1);
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!
2824
if (i->outgoing == 0) {
2825
cc_verbose(4, 1, VERBOSE_PREFIX_3 "%s: Disconnect case 3\n",
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);
2834
queue_cause_control(i, 0);
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",
2842
if ((i->state == CAPI_STATE_CONNECTED) &&
2843
(i->isdnstate & CAPI_ISDN_STATE_B3_UP)) {
2844
queue_cause_control(i, 1);
2847
/* wait for the 0x001e (PROGRESS), play audio and wait for a timeout from the network */
2850
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: Other case DISCONNECT INFO_IND\n",
2856
* incoming call SETUP
2858
static void capidev_handle_setup_element(_cmsg *CMSG, unsigned int PLCI, struct capi_pvt *i)
2860
if ((i->isdnstate & CAPI_ISDN_STATE_SETUP)) {
2861
cc_verbose(3, 1, VERBOSE_PREFIX_4 "%s: IE SETUP / SENDING-COMPLETE already received.\n",
2866
i->isdnstate |= CAPI_ISDN_STATE_SETUP;
2869
cc_log(LOG_ERROR, "No channel for interface!\n");
2873
if (i->isdnmode == CAPI_ISDNMODE_DID) {
2874
if (!strlen(i->dnid) && (i->immediate)) {
2875
start_pbx_on_match(i, PLCI, HEADER_MSGNUM(CMSG));
2878
start_pbx_on_match(i, PLCI, HEADER_MSGNUM(CMSG));
2886
static void capidev_handle_info_indication(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt *i)
2889
struct ast_frame fr = { AST_FRAME_NULL, };
2893
INFO_RESP_HEADER(&CMSG2, capi_ApplID, HEADER_MSGNUM(CMSG), PLCI);
2894
_capi_put_cmsg(&CMSG2);
2896
return_on_no_interface("INFO_IND");
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]);
2903
i->owner->hangupcause = INFO_IND_INFOELEMENT(CMSG)[2] & 0x7f;
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]);
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]);
2914
case 0x001c: /* Facility Q.932 */
2915
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element FACILITY\n",
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);
2923
case 0x0027: { /* Notification Indicator */
2925
if (INFO_IND_INFOELEMENT(CMSG)[0] > 0) {
2926
switch (INFO_IND_INFOELEMENT(CMSG)[1]) {
2928
desc = "User suspended";
2931
desc = "User resumed";
2934
desc = "Bearer service changed";
2937
desc = "User put on hold";
2940
desc = "User retrieved from hold";
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]);
2948
case 0x0028: /* DSP */
2949
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element DSP\n",
2952
case 0x0029: /* Date/Time */
2953
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element Date/Time %02d/%02d/%02d %02d:%02d\n",
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]);
2959
case 0x0070: /* Called Party Number */
2960
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element CALLED PARTY NUMBER\n",
2962
capidev_handle_did_digits(CMSG, PLCI, NCCI, i);
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;
2969
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element REDIRECTING NUMBER '%s' Reason=0x%02x\n",
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);
2979
i->owner->cid.cid_rdnis = strdup(p);
2982
case 0x00a1: /* Sending Complete */
2983
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element Sending Complete\n",
2985
capidev_handle_setup_element(CMSG, PLCI, i);
2987
case 0x4000: /* CHARGE in UNITS */
2988
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element CHARGE in UNITS\n",
2991
case 0x4001: /* CHARGE in CURRENCY */
2992
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element CHARGE in CURRENCY\n",
2995
case 0x8001: /* ALERTING */
2996
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element ALERTING\n",
2999
fr.frametype = AST_FRAME_CONTROL;
3000
fr.subclass = AST_CONTROL_RINGING;
3001
local_queue_frame(i, &fr);
3003
ast_setstate(i->owner, AST_STATE_RINGING);
3005
case 0x8002: /* CALL PROCEEDING */
3006
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element CALL PROCEEDING\n",
3008
fr.frametype = AST_FRAME_CONTROL;
3009
fr.subclass = AST_CONTROL_PROCEEDING;
3010
local_queue_frame(i, &fr);
3012
case 0x8003: /* PROGRESS */
3013
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element PROGRESS\n",
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.
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?)
3027
if (i->doB3 == CAPI_B3_DONT) {
3029
(i->owner->hangupcause == AST_CAUSE_USER_BUSY)) {
3030
queue_cause_control(i, 1);
3036
case 0x8005: /* SETUP */
3037
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element SETUP\n",
3039
capidev_handle_setup_element(CMSG, PLCI, i);
3041
case 0x8007: /* CONNECT */
3042
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element CONNECT\n",
3045
case 0x800d: /* SETUP ACK */
3046
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element SETUP ACK\n",
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;
3057
case 0x800f: /* CONNECT ACK */
3058
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element CONNECT ACK\n",
3061
case 0x8045: /* DISCONNECT */
3062
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element DISCONNECT\n",
3064
capidev_handle_info_disconnect(CMSG, PLCI, NCCI, i);
3066
case 0x804d: /* RELEASE */
3067
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element RELEASE\n",
3070
case 0x805a: /* RELEASE COMPLETE */
3071
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element RELEASE COMPLETE\n",
3074
case 0x8062: /* FACILITY */
3075
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element FACILITY\n",
3078
case 0x806e: /* NOTIFY */
3079
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element NOTIFY\n",
3082
case 0x807b: /* INFORMATION */
3083
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element INFORMATION\n",
3086
case 0x807d: /* STATUS */
3087
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: info element STATUS\n",
3091
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: unhandled INFO_IND %#x (PLCI=%#x)\n",
3092
i->vname, INFO_IND_INFONUMBER(CMSG), PLCI);
3101
static void capidev_handle_facility_indication(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt *i)
3104
struct ast_frame fr = { AST_FRAME_NULL, };
1280
3106
unsigned dtmflen;
3107
unsigned dtmfpos = 0;
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);
3114
return_on_no_interface("FACILITY_IND");
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",
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]));
3130
if (FACILITY_IND_FACILITYSELECTOR(CMSG) == FACILITYSELECTOR_DTMF) {
3132
if (FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[0] != (0xff)) {
3133
dtmflen = FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[0];
3134
FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG) += 1;
3136
dtmflen = read_capi_word(FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG) + 1);
3137
FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG) += 3;
3140
dtmf = (FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG))[dtmfpos];
3141
cc_verbose(1, 1, VERBOSE_PREFIX_4 "%s: c_dtmf = %c\n",
3143
if ((!(i->ntmode)) || (i->state == CAPI_STATE_CONNECTED)) {
3144
if ((dtmf == 'X') || (dtmf == 'Y')) {
3145
capi_handle_dtmf_fax(i);
3147
fr.frametype = AST_FRAME_DTMF;
3149
local_queue_frame(i, &fr);
3157
if (FACILITY_IND_FACILITYSELECTOR(CMSG) == FACILITYSELECTOR_SUPPLEMENTARY) {
3158
/* supplementary sservices */
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",
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]));
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",
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]));
3180
/* reason != 0x0000 == problem */
3181
i->state = CAPI_STATE_CONNECTED;
3182
i->PLCI = i->onholdPLCI;
3184
cc_verbose(1, 1, VERBOSE_PREFIX_3 "%s: PLCI=%#x retrieved\n",
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 */
3197
cc_log(LOG_WARNING, "%s: unable to put PLCI=%#x onhold, REASON = 0x%02x%02x, maybe you need to subscribe for this...\n",
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]));
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",
3216
static void capidev_handle_data_b3_indication(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt *i)
3219
struct ast_frame fr = { AST_FRAME_NULL, };
3220
unsigned char *b3buf = NULL;
1286
p = find_pipe(PLCI,CMSG->Messagenumber);
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);
1294
if (option_verbose > 5) {
1296
ast_verbose(VERBOSE_PREFIX_4 "sent DISCONNECT_RESP PLCI=%#x\n",PLCI);
1302
ast_log(LOG_NOTICE,"%s",capi_cmsg2str(CMSG));
1308
switch (CMSG->Subcommand) {
1310
switch (CMSG->Command) {
1311
case CAPI_DISCONNECT_B3:
1312
// ast_log(LOG_NOTICE,"DISCONNECT_B3_IND\n");
1314
DISCONNECT_B3_RESP_HEADER(&CMSG2, ast_capi_ApplID, CMSG->Messagenumber, 0);
1315
DISCONNECT_B3_RESP_NCCI(&CMSG2) = DISCONNECT_B3_IND_NCCI(CMSG);
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));
1320
if (option_verbose > 5) {
1322
ast_verbose(VERBOSE_PREFIX_4 "sent DISCONNECT_B3_RESP NCCI=%#x\n",(int)DISCONNECT_B3_IND_NCCI(CMSG));
1325
if (p->i->state == CAPI_STATE_BCONNECTED) {
1326
// passive disconnect
1327
p->i->state = CAPI_STATE_CONNECTED;
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;
1335
if ((error = _capi_put_cmsg(&CMSG2)) != 0) {
1336
ast_log(LOG_NOTICE, "error sending DISCONNECT_REQ PLCI=%#x\n",PLCI);
1338
if (option_verbose > 5) {
1340
ast_verbose(VERBOSE_PREFIX_4 "sent DISCONNECT_REQ PLCI=%#x\n",PLCI);
1344
if (p->i->state == CAPI_STATE_ONHOLD) {
1347
ast_mutex_lock(&contrlock);
1348
if (p->i->controller > 0) {
1349
capi_controllers[p->i->controller]->nfreebchannels++;
1351
ast_mutex_unlock(&contrlock);
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++;
1361
if ((error = _capi_put_cmsg(&CMSG2)) != 0) {
1362
ast_log(LOG_NOTICE, "error sending DISCONNECT_RESP PLCI=%#x\n",PLCI);
1364
if (option_verbose > 5) {
1366
ast_verbose(VERBOSE_PREFIX_4 "sent DISCONNECT_RESP PLCI=%#x\n",PLCI);
1370
if (PLCI == p->i->onholdPLCI) {
1371
// the caller onhold hung up (or ECTed away)
1372
p->i->onholdPLCI = 0;
1377
if (p->i->state == CAPI_STATE_DID) {
1378
if ((p->c) != NULL) {
1381
ast_log(LOG_WARNING, "unable to hangup channel on DID. Channel is NULL.\n");
1386
p->i->state = CAPI_STATE_DISCONNECTED;
1388
fr.frametype = AST_FRAME_CONTROL;
1389
if (DISCONNECT_IND_REASON(CMSG) == 0x34a2) {
1390
fr.subclass = AST_CONTROL_BUSY;
1392
fr.frametype = AST_FRAME_NULL;
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");
1403
ast_softhangup(p->c,AST_CONTROL_HANGUP);
1405
// dont ever hangup while hanging up!
1406
// ast_log(LOG_NOTICE,"no soft hangup by capi\n");
1413
/* fr.frametype = AST_FRAME_NULL;
1415
pipe_frame(p,(struct ast_frame *)&fr); */
1419
memcpy(&b3buf[AST_FRIENDLY_OFFSET],(char *)DATA_B3_IND_DATA(CMSG),DATA_B3_IND_DATALENGTH(CMSG));
1420
b3len = DATA_B3_IND_DATALENGTH(CMSG);
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);
1429
if (option_verbose > 6) {
1431
ast_verbose(VERBOSE_PREFIX_4 "sent DATA_B3_RESP (NCCI=%#x)\n",(int)DATA_B3_IND_NCCI(CMSG));
1435
ast_mutex_lock(&p->i->lockB3in);
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);
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]]));
1447
for(j=0;j<ECHO_EFFECTIVE_TX_COUNT;j++) {
1448
txavg += p->i->txavg[j];
1452
if( (txavg/ECHO_TXRX_RATIO) > rxavg) {
1454
memset(&b3buf[AST_FRIENDLY_OFFSET],255,b3len);
1456
memset(&b3buf[AST_FRIENDLY_OFFSET],84,b3len);
1459
ast_log(LOG_NOTICE,"SUPPRESSING ECHOrx=%d, tx=%d\n",rxavg,txavg);
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]]];
1468
for (j=0;j<b3len;j++) {
1469
b3buf[AST_FRIENDLY_OFFSET + j] = reversebits[(unsigned char)b3buf[AST_FRIENDLY_OFFSET + j]];
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]]];
1480
for (j=0;j<b3len;j++) {
1481
b3buf[AST_FRIENDLY_OFFSET + j] = reversebits[(unsigned char)b3buf[AST_FRIENDLY_OFFSET + j]];
1486
// just being paranoid ...
1487
/* if (p->c->_state != AST_STATE_UP) {
1488
ast_setstate(p->c,AST_STATE_UP);
1491
fr.frametype = AST_FRAME_VOICE;
1492
fr.subclass = capi_capability;
1493
fr.data = (char *)&b3buf[AST_FRIENDLY_OFFSET];
1496
fr.offset = AST_FRIENDLY_OFFSET;
1499
fr.delivery.tv_sec = 0;
1500
fr.delivery.tv_usec = 0;
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);
1507
if (FACILITY_IND_FACILITYSELECTOR(CMSG) == 0x0001) {
1509
if (FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[0] != (0xff)) {
1510
dtmflen = FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG)[0];
1511
FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG) += 1;
1513
dtmflen = ((__u16 *) (FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG) + 1))[0];
1514
FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG) += 3;
1517
dtmf = (FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG))[0];
1518
fr.frametype = AST_FRAME_DTMF;
1520
if (option_verbose > 1) {
1522
ast_verbose(VERBOSE_PREFIX_3 "c_dtmf = %c\n",dtmf);
1524
pipe_frame(p,(struct ast_frame *)&fr);
1527
if (FACILITY_IND_FACILITYSELECTOR(CMSG) == 0x0003) {
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]); */
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;
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]);
1549
// reason = 0x0000 == call on hold
1550
p->i->state = CAPI_STATE_ONHOLD;
1552
ast_log(LOG_NOTICE, "PLCI=%#x put onhold\n",(int)FACILITY_IND_PLCI(CMSG));
1557
error = FACILITY_RESP(&CMSG2, ast_capi_ApplID, CMSG->Messagenumber,FACILITY_IND_PLCI(CMSG),FACILITY_IND_FACILITYSELECTOR(CMSG),FACILITY_IND_FACILITYINDICATIONPARAMETER(CMSG));
1560
ast_log(LOG_ERROR,"error sending FACILITY_RESP (error=%#x)\n",error);
1562
if (option_verbose > 5) {
1564
ast_verbose(VERBOSE_PREFIX_4 "sent FACILITY_RESP (PLCI=%#x)\n",(int)FACILITY_IND_PLCI(CMSG));
1569
// ast_log(LOG_ERROR,"INFO_IND PLCI=%#x INFO# = %#x\n",PLCI,INFO_IND_INFONUMBER(CMSG));
1571
memset(&CMSG2,0,sizeof(_cmsg));
1572
error = INFO_RESP(&CMSG2,ast_capi_ApplID,CMSG->Messagenumber,PLCI);
1574
ast_log(LOG_ERROR,"error sending INFO_RESP (error=%#x)\n",error);
1577
if (option_verbose > 5) {
1579
ast_verbose(VERBOSE_PREFIX_4 "sent INFO_RESP (PLCI=%#x)\n",PLCI);
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]);
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");
1597
p->i->calledPartyIsISDN = 1;
1598
// ast_log(LOG_NOTICE,"I S D N\n");
1600
if(INFO_IND_INFOELEMENT(CMSG)[2] & 0x88) {
1601
// in-band info available
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);
1610
if (option_verbose > 1) {
1612
ast_verbose(VERBOSE_PREFIX_4 "sent early CONNECT_B3_REQ (PLCI=%#x)\n",PLCI);
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;
1626
if ((error = _capi_put_cmsg(&CMSG2)) != 0) {
1627
ast_log(LOG_NOTICE, "error sending DISCONNECT_REQ PLCI=%#x\n",PLCI);
1629
if (option_verbose > 1) {
1631
ast_verbose(VERBOSE_PREFIX_4 "sent DISCONNECT_REQ for onholdPLCI=%#x\n",PLCI);
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;
1642
return pipe_frame(p,(struct ast_frame *)&fr);
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;
1648
return pipe_frame(p,(struct ast_frame *)&fr);
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;
1657
return pipe_frame(p,(struct ast_frame *)&fr);
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
1665
// Handle DID digits
1666
if ((INFO_IND_INFONUMBER(CMSG) == 0x0070) && p->i->isdnmode && (p->c != NULL)) {
1668
char name[AST_CHANNEL_NAME] = "";
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);
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);
1679
search = search_did(p->c);
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");
1689
if (option_verbose > 2) {
1691
ast_verbose(VERBOSE_PREFIX_3 "started pbx on channel!\n");
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));
1703
if (option_verbose > 5) {
1705
ast_verbose(VERBOSE_PREFIX_4 "sent CONNECT_RESP for PLCI = %#x\n",(int)CONNECT_IND_PLCI(CMSG));
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);
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);
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));
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));
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);
1742
if (option_verbose > 5) {
1744
ast_verbose(VERBOSE_PREFIX_4 "sent CONNECT_ACTIVE_RESP (PLCI=%#x)\n",PLCI);
1747
// normal processing
1748
if (p->i->earlyB3 != 1) {
1749
p->i->state = CAPI_STATE_CONNECTED;
1751
// send a CONNECT_B3_REQ
1752
if (p->i->outgoing == 1) {
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);
1761
if (option_verbose > 1) {
1763
ast_verbose(VERBOSE_PREFIX_3 "sent CONNECT_B3_REQ (PLCI=%#x)\n",PLCI);
1768
// RESP already sent ... wait for CONNECT_B3_IND
1769
// ast_log(LOG_NOTICE,"waiting for CONNECT_B3_IND\n");
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);
1777
p->i->earlyB3 = 0; // not early anymore
1778
fr.frametype = AST_FRAME_CONTROL;
1779
fr.subclass = AST_CONTROL_ANSWER;
1781
return pipe_frame(p,(struct ast_frame *)&fr);
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;
1794
if ((error = _capi_put_cmsg(&CMSG2)) != 0) {
1795
ast_log(LOG_ERROR,"error sending CONNECT_B3_RESP (error=%#x)\n",error);
1798
if (option_verbose > 5) {
1800
ast_verbose(VERBOSE_PREFIX_4 "sent CONNECT_B3_RESP (NCCI=%#x)\n",p->i->NCCI);
1803
/* if (p->i->controller > 0) {
1804
capi_controllers[p->i->controller]->nfreebchannels--;
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
1811
CONNECT_B3_ACTIVE_RESP_HEADER(&CMSG2, ast_capi_ApplID, CMSG->Messagenumber, 0);
1812
CONNECT_B3_ACTIVE_RESP_NCCI(&CMSG2) = p->i->NCCI;
1814
if ((error = _capi_put_cmsg(&CMSG2)) != 0) {
1815
ast_log(LOG_ERROR,"error sending CONNECT_B3_ACTIVE_RESP (error=%#x)\n",error);
1818
if (option_verbose > 5) {
1820
ast_verbose(VERBOSE_PREFIX_4 "sent CONNECT_B3_ACTIVE_RESP (NCCI=%#x)\n",p->i->NCCI);
1824
ast_mutex_lock(&contrlock);
1825
if (p->i->controller > 0) {
1826
capi_controllers[p->i->controller]->nfreebchannels--;
1828
ast_mutex_unlock(&contrlock);
1830
p->i->state = CAPI_STATE_BCONNECTED;
1831
capi_echo_canceller(p->c,EC_FUNCTION_ENABLE);
1832
capi_detect_dtmf(p->c,1);
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;
1839
return pipe_frame(p,(struct ast_frame *)&fr);
1847
switch (CMSG->Command) {
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)) {
1853
p->i->state = CAPI_STATE_BCONNECTED;
1855
ast_log(LOG_NOTICE,"%s\n",capi_cmsg2str(CMSG));
1861
// ast_log(LOG_NOTICE,"DATA_B3_CONF (NCCI %#x) for DATAHANDLE %#x\n",DATA_B3_CONF_NCCI(CMSG),DATA_B3_CONF_DATAHANDLE(CMSG));
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) {
1871
if (option_verbose > 1) {
1873
ast_verbose(VERBOSE_PREFIX_2 "received CONNECT_CONF PLCI = %#x INFO = %#x\n",(int)CONNECT_CONF_PLCI(CMSG),CONNECT_CONF_INFO(CMSG));
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);
1880
// here, something has to be done -->
1881
fr.frametype = AST_FRAME_CONTROL;
1882
fr.subclass = AST_CONTROL_BUSY;
1884
return pipe_frame(p,(struct ast_frame *)&fr);
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);
1893
p->i->doB3 = AST_CAPI_B3_DONT;
1900
// ast_log(LOG_NOTICE,"returning\n");
1904
static void capi_handle_msg(_cmsg *CMSG) {
1905
struct ast_capi_pvt *i;
1910
MESSAGE_EXCHANGE_ERROR error;
1915
char buffer[AST_MAX_EXTENSION];
1916
struct capi_pipe *p;
1917
char *magicmsn = "*\0";
1918
char *emptyid = "\0";
1919
char *emptydnid = "s\0";
1921
#ifdef DEFLECT_ON_CIRCUITBUSY
1925
switch (CMSG->Subcommand) {
1929
switch (CMSG->Command) {
1930
case CAPI_CONNECT: // only connect_ind are global (not channel specific)
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) {
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) {
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);
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
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));
1961
if (option_verbose > 5) {
1963
ast_verbose(VERBOSE_PREFIX_4 "sent CONNECT_RESP for PLCI = %#x\n",(int)CONNECT_IND_PLCI(CMSG));
1966
// no need to pipe this
1973
// well...somebody is calling us. let's set up a channel
1974
ast_mutex_lock(&iflock);
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))) {
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);
1993
snprintf(i->cid, (sizeof(i->cid)-1), "%s%s", i->prefix, CID);
1995
strncpy(i->cid,emptyid,sizeof(i->cid)-1);
1998
strncpy(i->dnid,DNID,sizeof(i->dnid)-1);
2000
strncpy(i->dnid,emptydnid,sizeof(i->dnid)-1);
2002
i->controller=controller;
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);
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));
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);
2021
ast_pthread_mutex_init(&(p->lock),NULL);
2024
p->c = capi_new(i,AST_STATE_DOWN);
2025
i->state = CAPI_STATE_DID;
2027
p->c = capi_new(i,AST_STATE_RING);
2032
ast_mutex_unlock(&iflock);
2033
#ifdef DEFLECT_ON_CIRCUITBUSY
2034
if ((deflect == 1) && (i->deflect2)) {
2035
capi_deflect(p->c,i->deflect2);
2040
ast_log(LOG_ERROR,"creating pipe for PLCI=%#x failed\n",PLCI);
2044
msn = strtok(NULL,",");
2048
} // while interface list
2049
ast_mutex_unlock(&iflock); // obviously we are not called...so tell capi to ignore this call
2051
ast_log(LOG_ERROR,"did not find device for msn = %s\n",DNID);
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));
2059
if (option_verbose > 5) {
2061
ast_verbose(VERBOSE_PREFIX_4 "sent CONNECT_RESP for PLCI = %#x\n",(int)CONNECT_IND_PLCI(CMSG));
2064
ast_mutex_lock(&pipelock);
2065
if (pipelist == NULL) {
2066
capi_last_plci = PLCI;
2068
ast_mutex_unlock(&pipelock);
2069
// no need to pipe this
2071
// ast_mutex_unlock(&iflock);
2075
PLCI = FACILITY_IND_PLCI(CMSG) & 0xffff; // this is for you eicon
2076
if (option_verbose > 3) {
2078
ast_verbose(VERBOSE_PREFIX_3 "%s\n",capi_cmsg2str(CMSG));
2080
// ast_log(LOG_ERROR,"FACILITY_IND PLCI=%#x\n",PLCI);
2083
PLCI = INFO_IND_PLCI(CMSG);
2084
if (option_verbose > 3) {
2086
ast_verbose(VERBOSE_PREFIX_3 "%s\n",capi_cmsg2str(CMSG));
2088
// ast_log(LOG_ERROR,"INFO_IND PLCI=%#x INFO# = %#x\n",PLCI,INFO_IND_INFONUMBER(CMSG));
2090
case CAPI_CONNECT_ACTIVE:
2091
PLCI = CONNECT_ACTIVE_IND_PLCI(CMSG);
2092
if (option_verbose > 3) {
2094
ast_verbose(VERBOSE_PREFIX_3 "%s\n",capi_cmsg2str(CMSG));
2096
// ast_log(LOG_ERROR,"CONNECT_ACTIVE_IND PLCI=%#x\n",PLCI);
2098
case CAPI_CONNECT_B3:
2099
NCCI = CONNECT_B3_IND_NCCI(CMSG);
2100
PLCI = (NCCI << 16) >> 16;
2101
if (option_verbose > 3) {
2103
ast_verbose(VERBOSE_PREFIX_3 "%s\n",capi_cmsg2str(CMSG));
2105
// ast_log(LOG_ERROR,"CONNECT_B3_IND NCCI=%#x PLCI=%#x\n",NCCI,PLCI);
2107
case CAPI_CONNECT_B3_ACTIVE:
2108
NCCI = CONNECT_B3_IND_NCCI(CMSG);
2109
PLCI = (NCCI << 16) >> 16;
2110
if (option_verbose > 3) {
2112
ast_verbose(VERBOSE_PREFIX_3 "%s\n",capi_cmsg2str(CMSG));
2114
// ast_log(LOG_ERROR,"CONNECT_B3_ACTIVE_IND NCCI=%#x PLCI=%#x\n",NCCI,PLCI);
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);
2121
case CAPI_DISCONNECT_B3:
2122
NCCI = DISCONNECT_B3_IND_NCCI(CMSG);
2123
PLCI = (NCCI << 16) >> 16;
2124
if (option_verbose > 1) {
2126
ast_verbose(VERBOSE_PREFIX_2 "DISCONNECT_B3_IND NCCI=%#x\n",NCCI);
2129
case CAPI_DISCONNECT:
2130
PLCI = DISCONNECT_IND_PLCI(CMSG);
2131
if (option_verbose > 1) {
2133
ast_verbose(VERBOSE_PREFIX_2 "DISCONNECT_IND PLCI=%#x REASON=%#x\n",PLCI,DISCONNECT_IND_REASON(CMSG));
2137
ast_log(LOG_ERROR,"Command.Subcommand = %#x.%#x\n",CMSG->Command,CMSG->Subcommand);
2140
// confirmation msgs
2142
switch (CMSG->Command) {
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));
2151
ast_verbose (VERBOSE_PREFIX_3 "Echo canceller successfully set up (PLCI=%#x)\n",PLCI);
2154
if (option_verbose > 3) {
2156
ast_verbose(VERBOSE_PREFIX_3 "%s\n",capi_cmsg2str(CMSG));
2158
// ast_log(LOG_ERROR,"FACILITY_CONF NCCI=%#x INFO=%#x\n",(int)FACILITY_CONF_NCCI(CMSG),FACILITY_CONF_INFO(CMSG));
2161
PLCI = INFO_CONF_PLCI(CMSG);
2162
// ast_log(LOG_ERROR,"INFO_CONF PLCI=%#x INFO=%#x\n",PLCI,INFO_CONF_INFO(CMSG));
2165
PLCI = CONNECT_CONF_PLCI(CMSG);
2166
if (option_verbose > 3) {
2168
ast_verbose(VERBOSE_PREFIX_3 "%s\n",capi_cmsg2str(CMSG));
2170
// ast_log(LOG_ERROR,"CONNECT_CONF PLCI=%#x INFO=%#x MN=%#x\n",PLCI,CONNECT_CONF_INFO(CMSG),CMSG->Messagenumber);
2172
case CAPI_DISCONNECT:
2173
PLCI = DISCONNECT_CONF_PLCI(CMSG);
2174
if (option_verbose > 3) {
2176
ast_verbose(VERBOSE_PREFIX_3 "%s\n",capi_cmsg2str(CMSG));
2178
// ast_log(LOG_ERROR,"DISCONNECT_CONF PLCI=%#x INFO=%#x MN=%#x\n",PLCI,DISCONNECT_CONF_INFO(CMSG),CMSG->Messagenumber);
2180
case CAPI_DISCONNECT_B3:
2181
NCCI = DISCONNECT_B3_CONF_NCCI(CMSG);
2182
PLCI = (NCCI << 16) >> 16;
2183
if (option_verbose > 3) {
2185
ast_verbose(VERBOSE_PREFIX_3 "%s\n",capi_cmsg2str(CMSG));
2187
// ast_log(LOG_ERROR,"DISCONNECT_B3_CONF NCCI=%#x INFO=%#x MN=%#x\n",NCCI,DISCONNECT_B3_CONF_INFO(CMSG),CMSG->Messagenumber);
2189
case CAPI_CONNECT_B3:
2190
NCCI = CONNECT_B3_CONF_NCCI(CMSG);
2191
PLCI = (NCCI << 16) >> 16;
2192
if (option_verbose > 3) {
2194
ast_verbose(VERBOSE_PREFIX_3 "%s\n",capi_cmsg2str(CMSG));
2196
// ast_log(LOG_ERROR,"CONNECT_B3_CONF PLCI=%#x INFO=%#x MN=%#x\n",PLCI,CONNECT_B3_CONF_INFO(CMSG),CMSG->Messagenumber);
2199
PLCI = ALERT_CONF_PLCI(CMSG);
2200
if (option_verbose > 3) {
2202
ast_verbose(VERBOSE_PREFIX_3 "%s\n",capi_cmsg2str(CMSG));
2204
// ast_log(LOG_ERROR,"ALERT_CONF PLCI=%#x\n",PLCI);
2207
NCCI = DATA_B3_CONF_NCCI(CMSG);
2208
PLCI = (NCCI << 16) >> 16;
2209
if (option_verbose > 5) {
2211
ast_verbose(VERBOSE_PREFIX_3 "%s\n",capi_cmsg2str(CMSG));
2213
// ast_log(LOG_ERROR,"DATA_B3_CONF NCCI=%#x PLCI=%#x\n",NCCI,PLCI);
2216
ast_log(LOG_ERROR,"Command.Subcommand = %#x.%#x\n",CMSG->Command,CMSG->Subcommand);
2221
pipe_msg(PLCI,CMSG);
2230
// module stuff, monitor...
2232
static void *do_monitor(void *data) {
2237
if (ast_mutex_lock(&monlock)) {
2238
ast_log(LOG_ERROR,"Unable to get monitor lock!\n");
2241
// do some nifty stuff
2242
ast_mutex_unlock(&monlock);
2244
monCMSG = malloc(sizeof(_cmsg));
2245
memset(monCMSG,0,sizeof(_cmsg));
2246
switch(Info = check_wait_get_cmsg(monCMSG)) {
2249
ast_verbose(VERBOSE_PREFIX_3 "%s\n",capi_cmsg2str(monCMSG));
2250
capi_handle_msg(monCMSG);
2253
// CAPI queue is empty
2256
// something is wrong!
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");
2271
if (monitor_thread == pthread_self()) {
2272
ast_mutex_unlock(&monlock);
2273
ast_log(LOG_WARNING,"Unable to kill myself!\n");
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");
2288
static void capi_gains(struct ast_capi_gains *g,float rxgain,float txgain) {
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);
2299
for (i=0;i<256;i++) {
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);
2311
for (i=0;i<256;i++) {
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) {
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) {
2323
struct ast_capi_pvt *tmp;
2327
unsigned long contrmap=0;
2329
for (i=0;i<devices;i++) {
2330
tmp = malloc(sizeof(struct ast_capi_pvt));
2331
memset(tmp, 0, sizeof(struct ast_capi_pvt));
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);
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);
2348
contr = strtok(NULL,",");
2350
tmp->controllers = contrmap;
2351
capi_used_controllers |= contrmap;
2352
tmp->controller = 0;
2355
tmp->onholdPLCI = 0;
2356
tmp->doEC = echocancel;
2357
tmp->ecOption = ecoption;
2358
tmp->ecTail = ectail;
2359
tmp->isdnmode = isdnmode;
2361
tmp->callgroup = callgroup;
2365
tmp->rxgain = rxgain;
2366
tmp->txgain = txgain;
2367
capi_gains(&tmp->g,rxgain,txgain);
2369
#ifdef DEFLECT_ON_CIRCUITBUSY
2370
strncpy(tmp->deflect2, deflect2, sizeof(tmp->deflect2)-1);
2372
#ifndef FORCE_SOFTWARE_DTMF
2373
if (softdtmf == 1) {
2376
#ifndef FORCE_SOFTWARE_DTMF
2381
tmp->next = iflist; // prepend
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);
2395
void supported_sservices(struct ast_capi_controller *cp) {
2396
MESSAGE_EXCHANGE_ERROR error;
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
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);
2412
if (option_verbose > 5) {
2413
ast_verbose(VERBOSE_PREFIX_4 "sent FACILITY_REQ (CONTROLLER=%#x)\n",cp->controller);
2420
error = capi20_waitformessage(ast_capi_ApplID,&tv);
2421
error = capi_get_cmsg(&CMSG2,ast_capi_ApplID);
2422
// error = check_wait_get_cmsg(&CMSG2);
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));
2432
// parse supported sservices
2433
if (FACILITY_CONF_FACILITYSELECTOR(&CMSG2) == 0x0003) {
2435
if (FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[4] == 0) {
2436
if ((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[6] & 1) == 1) {
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);
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);
3240
return_on_no_interface("DATA_B3_IND");
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",
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));
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 */
3261
if ((i->isdnstate & CAPI_ISDN_STATE_RTP)) {
3262
struct ast_frame *f = capi_read_rtp(i, b3buf, b3len);
3264
local_queue_frame(i, f);
3268
if (i->B3q < (((CAPI_MAX_B3_BLOCKS - 1) * CAPI_MAX_B3_BLOCK_SIZE) + 1)) {
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)]]);
3278
rxavg += abs(capiALAW2INT[ reversebits[*(b3buf + j)]]);
3282
for (j = 0; j < ECHO_EFFECTIVE_TX_COUNT; j++) {
3283
txavg += i->txavg[j];
3287
if ( (txavg / ECHO_TXRX_RATIO) > rxavg) {
3288
if (capi_capability == AST_FORMAT_ULAW) {
3289
memset(b3buf, 255, b3len);
3291
memset(b3buf, 85, b3len);
3293
cc_verbose(6, 1, VERBOSE_PREFIX_3 "%s: SUPPRESSING ECHO rx=%d, tx=%d\n",
3294
i->vname, rxavg, txavg);
3297
if (i->rxgain == 1.0) {
3298
for (j = 0; j < b3len; j++) {
3299
*(b3buf + j) = reversebits[*(b3buf + j)];
3302
for (j = 0; j < b3len; j++) {
3303
*(b3buf + j) = reversebits[i->g.rxgains[*(b3buf + j)]];
3308
fr.frametype = AST_FRAME_VOICE;
3309
fr.subclass = capi_capability;
3313
fr.offset = AST_FRIENDLY_OFFSET;
3315
fr.delivery = ast_tv(0,0);
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);
3324
* signal 'answer' to PBX
3326
static void capi_signal_answer(struct capi_pvt *i)
3328
struct ast_frame fr = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER, };
3330
if (i->outgoing == 1) {
3331
local_queue_frame(i, &fr);
3336
* send the next data
3338
static void capidev_send_faxdata(struct capi_pvt *i)
3340
unsigned char faxdata[CAPI_MAX_B3_BLOCK_SIZE];
3344
if ((i->fFax) && (!(feof(i->fFax)))) {
3345
len = fread(faxdata, 1, CAPI_MAX_B3_BLOCK_SIZE, i->fFax);
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",
3356
_capi_put_cmsg(&CMSG);
3360
/* finished send fax, so we hangup */
3361
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: completed faxsend.\n",
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);
3369
* CAPI MANUFACTURER_IND
3371
static void capidev_handle_manufacturer_indication(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt *i)
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);
3380
return_on_no_interface("MANUFACTURER_IND");
3382
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: Ignored MANUFACTURER_IND Id=0x%x \n",
3383
i->vname, MANUFACTURER_IND_MANUID(CMSG));
3389
* CAPI CONNECT_ACTIVE_IND
3391
static void capidev_handle_connect_active_indication(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt *i)
3395
CONNECT_ACTIVE_RESP_HEADER(&CMSG2, capi_ApplID, HEADER_MSGNUM(CMSG), 0);
3396
CONNECT_ACTIVE_RESP_PLCI(&CMSG2) = PLCI;
3397
_capi_put_cmsg(&CMSG2);
3399
return_on_no_interface("CONNECT_ACTIVE_IND");
3401
if (i->state == CAPI_STATE_DISCONNECTING) {
3402
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: CONNECT_ACTIVE in DISCONNECTING.\n",
3407
i->state = CAPI_STATE_CONNECTED;
3409
if ((i->FaxState & CAPI_FAX_STATE_SENDMODE)) {
3414
if ((i->owner) && (i->FaxState & CAPI_FAX_STATE_ACTIVE)) {
3415
ast_setstate(i->owner, AST_STATE_UP);
3417
ast_cdr_answer(i->owner->cdr);
3421
/* normal processing */
3423
if (!(i->isdnstate & CAPI_ISDN_STATE_B3_UP)) {
3424
/* send a CONNECT_B3_REQ */
3425
if (i->outgoing == 1) {
3430
/* RESP already sent ... wait for CONNECT_B3_IND */
3433
capi_signal_answer(i);
3439
* CAPI CONNECT_B3_ACTIVE_IND
3441
static void capidev_handle_connect_b3_active_indication(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt *i)
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);
3450
return_on_no_interface("CONNECT_ACTIVE_B3_IND");
3452
capi_controllers[i->controller]->nfreebchannels--;
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",
3460
i->isdnstate |= CAPI_ISDN_STATE_B3_UP;
3461
i->isdnstate &= ~CAPI_ISDN_STATE_B3_PEND;
3463
if (i->bproto == CC_BPROTO_RTP) {
3464
i->isdnstate |= CAPI_ISDN_STATE_RTP;
3466
i->isdnstate &= ~CAPI_ISDN_STATE_RTP;
3467
i->B3q = (CAPI_MAX_B3_BLOCK_SIZE * 3);
3470
if ((i->FaxState & CAPI_FAX_STATE_SENDMODE)) {
3471
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: Start sending fax.\n",
3473
capidev_send_faxdata(i);
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",
3484
cc_log(LOG_ERROR, "%s: No channel for interface!\n",
3489
if (i->FaxState & CAPI_FAX_STATE_ACTIVE) {
3490
cc_verbose(3, 1, VERBOSE_PREFIX_3 "%s: Fax connection, no EC/DTMF\n",
3493
capi_echo_canceller(i->owner, EC_FUNCTION_ENABLE);
3494
capi_detect_dtmf(i->owner, 1);
3497
if (i->state == CAPI_STATE_CONNECTED) {
3498
capi_signal_answer(i);
3504
* CAPI DISCONNECT_B3_IND
3506
static void capidev_handle_disconnect_b3_indication(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt *i)
3510
DISCONNECT_B3_RESP_HEADER(&CMSG2, capi_ApplID, HEADER_MSGNUM(CMSG), 0);
3511
DISCONNECT_B3_RESP_NCCI(&CMSG2) = NCCI;
3512
_capi_put_cmsg(&CMSG2);
3514
return_on_no_interface("DISCONNECT_B3_IND");
3516
i->isdnstate &= ~(CAPI_ISDN_STATE_B3_UP | CAPI_ISDN_STATE_B3_PEND);
3518
i->reasonb3 = DISCONNECT_B3_IND_REASON_B3(CMSG);
3521
if ((i->FaxState & CAPI_FAX_STATE_ACTIVE) && (i->owner)) {
3522
char buffer[CAPI_MAX_STRING];
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);
3533
pbx_builtin_setvar_helper(i->owner, "FAXREASONTEXT", "");
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);
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);
3559
capi_controllers[i->controller]->nfreebchannels++;
3563
* CAPI CONNECT_B3_IND
3565
static void capidev_handle_connect_b3_indication(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt *i)
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);
3576
return_on_no_interface("CONNECT_B3_IND");
3584
* CAPI DISCONNECT_IND
3586
static void capidev_handle_disconnect_indication(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt *i)
3589
struct ast_frame fr = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP, };
3592
DISCONNECT_RESP_HEADER(&CMSG2, capi_ApplID, HEADER_MSGNUM(CMSG) , 0);
3593
DISCONNECT_RESP_PLCI(&CMSG2) = PLCI;
3594
_capi_put_cmsg(&CMSG2);
3596
show_capi_info(i, DISCONNECT_IND_REASON(CMSG));
3598
return_on_no_interface("DISCONNECT_IND");
3601
i->state = CAPI_STATE_DISCONNECTED;
3603
i->reason = DISCONNECT_IND_REASON(CMSG);
3605
if ((i->owner) && (i->owner->hangupcause == 0)) {
3606
/* set hangupcause, in case there is no
3607
* "cause" information element:
3609
i->owner->hangupcause =
3610
((i->reason & 0xFF00) == 0x3400) ?
3611
i->reason & 0x7F : AST_CAUSE_NORMAL_CLEARING;
3614
if (i->FaxState & CAPI_FAX_STATE_ACTIVE) {
3616
switch (i->reason) {
3620
if (i->reasonb3 != 0)
3621
i->FaxState |= CAPI_FAX_STATE_ERROR;
3624
i->FaxState |= CAPI_FAX_STATE_ERROR;
3626
i->FaxState &= ~CAPI_FAX_STATE_ACTIVE;
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",
3635
capi_channel_task(i->owner, CAPI_CHANNEL_TASK_HANGUP);
3639
if (DISCONNECT_IND_REASON(CMSG) == 0x34a2) {
3640
fr.subclass = AST_CONTROL_CONGESTION;
3643
if (state == CAPI_STATE_DISCONNECTING) {
3644
interface_cleanup(i);
3646
local_queue_frame(i, &fr);
3654
static void capidev_handle_connect_indication(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt **interface)
3660
int callernplan = 0, callednplan = 0;
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";
3669
char bchannelinfo[2] = { '0', 0 };
3672
/* chan_capi does not support
3673
* double connect indications !
3674
* (This is used to update
3675
* telephone numbers and
3676
* other information)
3681
DNID = capi_number(CONNECT_IND_CALLEDPARTYNUMBER(CMSG), 1);
3685
if (CONNECT_IND_CALLEDPARTYNUMBER(CMSG)[0] > 1) {
3686
callednplan = (CONNECT_IND_CALLEDPARTYNUMBER(CMSG)[1] & 0x7f);
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);
3694
controller = PLCI & 0xff;
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);
3699
if (CONNECT_IND_BCHANNELINFORMATION(CMSG)) {
3700
bchannelinfo[0] = CONNECT_IND_BCHANNELINFORMATION(CMSG)[1] + '0';
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) {
3707
/* has already owner */
3710
if (i->controller != controller) {
3713
if (i->channeltype == CAPI_CHANNELTYPE_B) {
3714
if (bchannelinfo[0] != '0')
3717
if (bchannelinfo[0] == '0')
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))) {
3727
cc_copy_string(i->dnid, emptydnid, sizeof(i->dnid));
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)))) {
3740
cc_copy_string(i->dnid, DNID, sizeof(i->dnid));
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);
3750
snprintf(i->cid, (sizeof(i->cid)-1), "%s%s",
3753
cc_copy_string(i->cid, emptyid, sizeof(i->cid));
3755
i->cip = CONNECT_IND_CIPVALUE(CMSG);
3757
i->MessageNumber = HEADER_MSGNUM(CMSG);
3758
i->cid_ton = callernplan;
3760
capi_new(i, AST_STATE_DOWN);
3761
if (i->isdnmode == CAPI_ISDNMODE_DID) {
3762
i->state = CAPI_STATE_DID;
3764
i->state = CAPI_STATE_INCALL;
3768
interface_cleanup(i);
3771
i->owner->transfercapability = cip2tcap(i->cip);
3772
if (tcap_is_digital(i->owner->transfercapability)) {
3773
i->bproto = CC_BPROTO_TRANSPARENT;
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);
3780
cc_mutex_unlock(&iflock);
3781
cc_mutex_lock(&i->lock);
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);
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));
3795
/* TODO : set some more variables on incoming call */
3797
pbx_builtin_setvar_helper(i->owner, "ANI2", buffer);
3798
pbx_builtin_setvar_helper(i->owner, "SECONDCALLERID", buffer);
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));
3807
cc_mutex_unlock(&iflock);
3809
/* obviously we are not called...so tell capi to ignore this call */
3812
cc_log(LOG_WARNING, "did not find device for msn = %s\n", DNID);
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);
3823
* CAPI FACILITY_CONF
3825
static void capidev_handle_facility_confirmation(_cmsg *CMSG, unsigned int PLCI, unsigned int NCCI, struct capi_pvt *i)
3832
selector = FACILITY_CONF_FACILITYSELECTOR(CMSG);
3834
if (selector == FACILITYSELECTOR_DTMF) {
3835
cc_verbose(2, 1, VERBOSE_PREFIX_4 "%s: DTMF conf(PLCI=%#x)\n",
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",
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",
3849
cc_verbose(3, 0, VERBOSE_PREFIX_3 "%s: Echo canceller successfully set up (PLCI=%#x)\n",
3854
if (selector == FACILITYSELECTOR_SUPPLEMENTARY) {
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",
3865
if (selector == FACILITYSELECTOR_LINE_INTERCONNECT) {
3866
if ((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(CMSG)[1] == 0x1) &&
3867
(FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(CMSG)[2] == 0x0)) {
3869
if (FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(CMSG)[0] > 12) {
3870
show_capi_info(i, read_capi_word(&FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(CMSG)[12]));
3874
if (FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(CMSG)[0] > 12) {
3875
show_capi_info(i, read_capi_word(&FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(CMSG)[12]));
3880
cc_log(LOG_ERROR, "%s: unhandled FACILITY_CONF 0x%x\n",
3881
i->vname, FACILITY_CONF_FACILITYSELECTOR(CMSG));
3885
* show error in confirmation
3887
static void show_capi_conf_error(struct capi_pvt *i,
3888
unsigned int PLCI, u_int16_t wInfo,
3891
const char *name = channeltype;
3896
if ((wCmd == CAPI_P_CONF(ALERT)) && (wInfo == 0x0003)) {
3897
/* Alert already sent by another application */
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);
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);
3915
* check special conditions, wake waiting threads and send outstanding commands
3916
* for the given interface
3918
static void capidev_post_handling(struct capi_pvt *i, _cmsg *CMSG)
3920
unsigned short capicommand = CAPICMD(CMSG->Command, CMSG->Subcommand);
3922
if ((i->waitevent == CAPI_WAITEVENT_B3_UP) &&
3923
((i->isdnstate & CAPI_ISDN_STATE_B3_UP))) {
3925
ast_cond_signal(&i->event_trigger);
3926
cc_verbose(4, 1, "%s: found and signal for b3 up state.\n",
3930
if ((i->waitevent == CAPI_WAITEVENT_B3_DOWN) &&
3931
(!(i->isdnstate & (CAPI_ISDN_STATE_B3_UP | CAPI_ISDN_STATE_B3_PEND)))) {
3933
ast_cond_signal(&i->event_trigger);
3934
cc_verbose(4, 1, "%s: found and signal for b3 down state.\n",
3938
if ((i->waitevent == CAPI_WAITEVENT_FAX_FINISH) &&
3939
(!(i->FaxState & CAPI_FAX_STATE_ACTIVE))) {
3941
ast_cond_signal(&i->event_trigger);
3942
cc_verbose(4, 1, "%s: found and signal for finished fax state.\n",
3946
if ((i->waitevent == CAPI_WAITEVENT_ANSWER_FINISH) &&
3947
(i->state != CAPI_STATE_ANSWERING)) {
3949
ast_cond_signal(&i->event_trigger);
3950
cc_verbose(4, 1, "%s: found and signal for finished ANSWER state.\n",
3954
if (i->waitevent == capicommand) {
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));
3966
static void capidev_handle_msg(_cmsg *CMSG)
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);
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));
3979
cc_verbose(4, 1, "%s\n", capi_cmsg2str(CMSG));
3983
cc_mutex_lock(&i->lock);
3985
/* main switch table */
3992
case CAPI_P_IND(CONNECT):
3993
capidev_handle_connect_indication(CMSG, PLCI, NCCI, &i);
3995
case CAPI_P_IND(DATA_B3):
3996
capidev_handle_data_b3_indication(CMSG, PLCI, NCCI, i);
3998
case CAPI_P_IND(CONNECT_B3):
3999
capidev_handle_connect_b3_indication(CMSG, PLCI, NCCI, i);
4001
case CAPI_P_IND(CONNECT_B3_ACTIVE):
4002
capidev_handle_connect_b3_active_indication(CMSG, PLCI, NCCI, i);
4004
case CAPI_P_IND(DISCONNECT_B3):
4005
capidev_handle_disconnect_b3_indication(CMSG, PLCI, NCCI, i);
4007
case CAPI_P_IND(DISCONNECT):
4008
capidev_handle_disconnect_indication(CMSG, PLCI, NCCI, i);
4010
case CAPI_P_IND(FACILITY):
4011
capidev_handle_facility_indication(CMSG, PLCI, NCCI, i);
4013
case CAPI_P_IND(INFO):
4014
capidev_handle_info_indication(CMSG, PLCI, NCCI, i);
4016
case CAPI_P_IND(CONNECT_ACTIVE):
4017
capidev_handle_connect_active_indication(CMSG, PLCI, NCCI, i);
4019
case CAPI_P_IND(MANUFACTURER):
4020
capidev_handle_manufacturer_indication(CMSG, PLCI, NCCI, i);
4024
* CAPI confirmations
4027
case CAPI_P_CONF(FACILITY):
4028
wInfo = FACILITY_CONF_INFO(CMSG);
4029
capidev_handle_facility_confirmation(CMSG, PLCI, NCCI, i);
4031
case CAPI_P_CONF(CONNECT):
4032
wInfo = CONNECT_CONF_INFO(CMSG);
4034
cc_log(LOG_ERROR, "CAPI: CONNECT_CONF for already "
4035
"defined interface received\n");
4038
i = find_interface_by_msgnum(wMsgNum);
4039
if ((i == NULL) || (!i->owner))
4041
cc_verbose(1, 1, VERBOSE_PREFIX_3 "%s: received CONNECT_CONF PLCI = %#x\n",
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);
4052
case CAPI_P_CONF(CONNECT_B3):
4053
wInfo = CONNECT_B3_CONF_INFO(CMSG);
4054
if(i == NULL) break;
4058
i->isdnstate &= ~(CAPI_ISDN_STATE_B3_UP | CAPI_ISDN_STATE_B3_PEND);
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;
4074
case CAPI_P_CONF(SELECT_B_PROTOCOL):
4075
wInfo = SELECT_B_PROTOCOL_CONF_INFO(CMSG);
4076
if(i == NULL) break;
4078
i->isdnstate &= ~CAPI_ISDN_STATE_B3_SELECT;
4079
if ((i->outgoing) && (i->FaxState & CAPI_FAX_STATE_SENDMODE)) {
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);
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)) {
4093
if ((i) && (i->FaxState & CAPI_FAX_STATE_SENDMODE)) {
4094
capidev_send_faxdata(i);
4098
case CAPI_P_CONF(DISCONNECT):
4099
wInfo = DISCONNECT_CONF_INFO(CMSG);
4102
case CAPI_P_CONF(DISCONNECT_B3):
4103
wInfo = DISCONNECT_B3_CONF_INFO(CMSG);
4106
case CAPI_P_CONF(LISTEN):
4107
wInfo = LISTEN_CONF_INFO(CMSG);
4110
case CAPI_P_CONF(INFO):
4111
wInfo = INFO_CONF_INFO(CMSG);
4115
cc_log(LOG_ERROR, "CAPI: Command=%s,0x%04x",
4116
capi_command_to_string(wCmd), wCmd);
4120
if (wInfo != 0xffff) {
4122
show_capi_conf_error(i, PLCI, wInfo, wCmd);
4124
show_capi_info(i, wInfo);
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);
4133
capidev_post_handling(i, CMSG);
4134
cc_mutex_unlock(&i->lock);
4143
static int pbx_capi_call_deflect(struct ast_channel *c, char *param)
4145
struct capi_pvt *i = CC_CHANNEL_PVT(c);
4153
cc_log(LOG_WARNING, "capi deflection requires an argument (destination phone number)\n");
4156
number = strsep(¶m, "|");
4157
numberlen = strlen(number);
4160
cc_log(LOG_WARNING, "capi deflection requires an argument (destination phone number)\n");
4163
if (numberlen > 35) {
4164
cc_log(LOG_WARNING, "capi deflection does only support phone number up to 35 digits\n");
4167
if (!(capi_controllers[i->controller]->CD)) {
4168
cc_log(LOG_NOTICE,"%s: CALL DEFLECT for %s not supported by controller.\n",
4173
cc_mutex_lock(&i->lock);
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");
4182
if (i->state != CAPI_STATE_ALERTING) {
4186
fac[0] = 0x0a + numberlen; /* length */
4187
fac[1] = 0x0d; /* call deflection */
4189
fac[3] = 0x07 + numberlen; /* struct len */
4190
fac[4] = 0x01; /* display of own address allowed */
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 */
4198
memcpy((unsigned char *)fac + 10, number, numberlen);
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;
4205
_capi_put_cmsg_wait_conf(i, &CMSG);
4207
cc_mutex_unlock(&i->lock);
4209
cc_verbose(2, 1, VERBOSE_PREFIX_3 "%s: sent FACILITY_REQ for CD PLCI = %#x\n",
4216
* retrieve a hold on call
4218
static int pbx_capi_retrieve(struct ast_channel *c, char *param)
4220
struct capi_pvt *i = CC_CHANNEL_PVT(c);
4223
unsigned int plci = 0;
4225
if (c->tech->type == channeltype) {
4226
plci = i->onholdPLCI;
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)
4238
cc_mutex_unlock(&iflock);
4245
cc_log(LOG_WARNING, "%s is not valid or not on capi hold to retrieve!\n",
4250
if ((i->state != CAPI_STATE_ONHOLD) &&
4251
(i->isdnstate & CAPI_ISDN_STATE_HOLD)) {
4253
while ((waitcount > 0) && (i->state != CAPI_STATE_ONHOLD)) {
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",
4264
cc_verbose(2, 1, VERBOSE_PREFIX_4 "%s: using PLCI=%#x for retrieve\n",
4267
if (!(capi_controllers[i->controller]->holdretrieve)) {
4268
cc_log(LOG_NOTICE,"%s: RETRIEVE for %s not supported by controller.\n",
4273
fac[0] = 3; /* len */
4274
fac[1] = 0x03; /* retrieve */
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;
4283
_capi_put_cmsg(&CMSG);
4284
cc_verbose(2, 1, VERBOSE_PREFIX_4 "%s: sent RETRIEVE for PLCI=%#x\n",
4287
i->isdnstate &= ~CAPI_ISDN_STATE_HOLD;
4288
pbx_builtin_setvar_helper(i->owner, "_CALLERHOLDID", NULL);
4294
* explicit transfer a held call
4296
static int pbx_capi_ect(struct ast_channel *c, char *param)
4298
struct capi_pvt *i = CC_CHANNEL_PVT(c);
4299
struct capi_pvt *ii = NULL;
4303
unsigned int plci = 0;
4305
if ((id = pbx_builtin_getvar_helper(c, "CALLERHOLDID"))) {
4306
plci = (unsigned int)strtoul(id, NULL, 0);
4310
plci = (unsigned int)strtoul(param, NULL, 0);
4314
cc_log(LOG_WARNING, "%s: No id for ECT !\n", i->vname);
4318
cc_mutex_lock(&iflock);
4319
for (ii = iflist; ii; ii = ii->next) {
4320
if (ii->onholdPLCI == plci)
4323
cc_mutex_unlock(&iflock);
4326
cc_log(LOG_WARNING, "%s: 0x%x is not on hold !\n",
4331
cc_verbose(2, 1, VERBOSE_PREFIX_4 "%s: using PLCI=%#x for ECT\n",
4334
if (!(capi_controllers[i->controller]->ECT)) {
4335
cc_log(LOG_WARNING, "%s: ECT for %s not supported by controller.\n",
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);
4346
cc_disconnect_b3(i, 1);
4348
if (i->state != CAPI_STATE_CONNECTED) {
4349
cc_log(LOG_WARNING, "%s: destination not connected for ECT\n",
4354
fac[0] = 7; /* len */
4355
fac[1] = 0x06; /* ECT (function) */
4357
fac[3] = 4; /* len / sservice specific parameter , cstruct */
4358
write_capi_dword(&(fac[4]), plci);
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;
4366
cc_mutex_lock(&ii->lock);
4367
_capi_put_cmsg_wait_conf(ii, &CMSG);
4369
ii->isdnstate &= ~CAPI_ISDN_STATE_HOLD;
4370
ii->isdnstate |= CAPI_ISDN_STATE_ECT;
4371
i->isdnstate |= CAPI_ISDN_STATE_ECT;
4373
cc_mutex_unlock(&ii->lock);
4375
cc_verbose(2, 1, VERBOSE_PREFIX_4 "%s: sent ECT for PLCI=%#x to PLCI=%#x\n",
4376
i->vname, plci, i->PLCI);
4384
static int pbx_capi_hold(struct ast_channel *c, char *param)
4386
struct capi_pvt *i = CC_CHANNEL_PVT(c);
4391
/* TODO: support holdtype notify */
4393
if ((i->isdnstate & CAPI_ISDN_STATE_HOLD)) {
4394
cc_log(LOG_NOTICE,"%s: %s already on hold.\n",
4399
if (!(i->isdnstate & CAPI_ISDN_STATE_B3_UP)) {
4400
cc_log(LOG_NOTICE,"%s: Cannot put on hold %s while not connected.\n",
4404
if (!(capi_controllers[i->controller]->holdretrieve)) {
4405
cc_log(LOG_NOTICE,"%s: HOLD for %s not supported by controller.\n",
4410
fac[0] = 3; /* len */
4411
fac[1] = 0x02; /* this is a HOLD up */
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;
4420
_capi_put_cmsg(&CMSG);
4421
cc_verbose(2, 1, VERBOSE_PREFIX_4 "%s: sent HOLD for PLCI=%#x\n",
4424
i->onholdPLCI = i->PLCI;
4425
i->isdnstate |= CAPI_ISDN_STATE_HOLD;
4427
snprintf(buffer, sizeof(buffer) - 1, "%d", i->PLCI);
4429
pbx_builtin_setvar_helper(i->owner, param, buffer);
4431
pbx_builtin_setvar_helper(i->owner, "_CALLERHOLDID", buffer);
4437
* report malicious call
4439
static int pbx_capi_malicious(struct ast_channel *c, char *param)
4441
struct capi_pvt *i = CC_CHANNEL_PVT(c);
4445
if (!(capi_controllers[i->controller]->MCID)) {
4446
cc_log(LOG_NOTICE, "%s: MCID for %s not supported by controller.\n",
4451
fac[0] = 3; /* len */
4452
fac[1] = 0x0e; /* MCID */
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;
4461
cc_mutex_lock(&i->lock);
4462
_capi_put_cmsg_wait_conf(i, &CMSG);
4463
cc_mutex_unlock(&i->lock);
4465
cc_verbose(2, 1, VERBOSE_PREFIX_4 "%s: sent MCID for PLCI=%#x\n",
4474
static int pbx_capi_echocancel(struct ast_channel *c, char *param)
4476
struct capi_pvt *i = CC_CHANNEL_PVT(c);
4479
cc_log(LOG_WARNING, "Parameter for echocancel missing.\n");
4482
if (ast_true(param)) {
4484
capi_echo_canceller(c, EC_FUNCTION_ENABLE);
4485
} else if (ast_false(param)) {
4486
capi_echo_canceller(c, EC_FUNCTION_DISABLE);
4489
cc_log(LOG_WARNING, "Parameter for echocancel invalid.\n");
4492
cc_verbose(2, 0, VERBOSE_PREFIX_4 "%s: echocancel switched %s\n",
4493
i->vname, i->doEC ? "ON":"OFF");
4500
static int pbx_capi_echosquelch(struct ast_channel *c, char *param)
4502
struct capi_pvt *i = CC_CHANNEL_PVT(c);
4505
cc_log(LOG_WARNING, "Parameter for echosquelch missing.\n");
4508
if (ast_true(param)) {
4510
} else if (ast_false(param)) {
4513
cc_log(LOG_WARNING, "Parameter for echosquelch invalid.\n");
4516
cc_verbose(2, 0, VERBOSE_PREFIX_4 "%s: echosquelch switched %s\n",
4517
i->vname, i->doES ? "ON":"OFF");
4524
static int pbx_capi_holdtype(struct ast_channel *c, char *param)
4526
struct capi_pvt *i = CC_CHANNEL_PVT(c);
4529
cc_log(LOG_WARNING, "Parameter for holdtype missing.\n");
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;
4539
cc_log(LOG_WARNING, "Parameter for holdtype invalid.\n");
4542
cc_verbose(2, 0, VERBOSE_PREFIX_4 "%s: holdtype switched to %s\n",
4548
* set early-B3 (progress) for incoming connections
4549
* (only for NT mode)
4551
static int pbx_capi_signal_progress(struct ast_channel *c, char *param)
4553
struct capi_pvt *i = CC_CHANNEL_PVT(c);
4555
if ((i->state != CAPI_STATE_DID) && (i->state != CAPI_STATE_INCALL)) {
4556
cc_log(LOG_DEBUG, "wrong channel state to signal PROGRESS\n");
4560
cc_log(LOG_WARNING, "PROGRESS sending for non NT-mode not possible\n");
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",
4569
cc_select_b(i, NULL);
4575
* struct of capi commands
4577
static struct capicommands_s {
4579
int (*cmd)(struct ast_channel *, char *);
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 },
4597
* capi command interface
4599
static int pbx_capicommand_exec(struct ast_channel *chan, void *data)
4602
struct localuser *u;
4605
char *command, *params;
4606
struct capicommands_s *capicmd = &capicommands[0];
4609
cc_log(LOG_WARNING, "capiCommand requires arguments\n");
4615
s = ast_strdupa(data);
4617
command = strsep(&stringp, "|");
4619
cc_verbose(2, 1, VERBOSE_PREFIX_3 "capiCommand: '%s' '%s'\n",
4622
while(capicmd->cmd) {
4623
if (!strcasecmp(capicmd->cmdname, command))
4627
if (!capicmd->cmd) {
4628
LOCAL_USER_REMOVE(u);
4629
cc_log(LOG_WARNING, "Unknown command '%s' for capiCommand\n",
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");
4640
res = (capicmd->cmd)(chan, params);
4642
LOCAL_USER_REMOVE(u);
4647
* we don't support own indications
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)
4652
static int pbx_capi_indicate(struct ast_channel *c, int condition)
4655
struct capi_pvt *i = CC_CHANNEL_PVT(c);
4663
cc_mutex_lock(&i->lock);
4665
switch (condition) {
4666
case AST_CONTROL_RINGING:
4667
cc_verbose(3, 1, VERBOSE_PREFIX_2 "%s: Requested RINGING-Indication for %s\n",
4669
/* TODO somehow enable unhold on ringing, but when wanted only */
4671
if (i->isdnstate & CAPI_ISDN_STATE_HOLD)
4672
pbx_capi_retrieve(c, NULL);
4675
if ((i->isdnstate & CAPI_ISDN_STATE_B3_UP)) {
4678
pbx_capi_signal_progress(c, NULL);
4681
ret = pbx_capi_alert(c);
4684
case AST_CONTROL_BUSY:
4685
cc_verbose(3, 1, VERBOSE_PREFIX_2 "%s: Requested BUSY-Indication for %s\n",
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);
4695
if ((i->isdnstate & CAPI_ISDN_STATE_HOLD))
4696
pbx_capi_retrieve(c, NULL);
4698
case AST_CONTROL_CONGESTION:
4699
cc_verbose(3, 1, VERBOSE_PREFIX_2 "%s: Requested CONGESTION-Indication for %s\n",
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);
4709
if ((i->isdnstate & CAPI_ISDN_STATE_HOLD))
4710
pbx_capi_retrieve(c, NULL);
4712
case AST_CONTROL_PROGRESS:
4713
cc_verbose(3, 1, VERBOSE_PREFIX_2 "%s: Requested PROGRESS-Indication for %s\n",
4715
if (i->ntmode) pbx_capi_signal_progress(c, NULL);
4717
case AST_CONTROL_PROCEEDING:
4718
cc_verbose(3, 1, VERBOSE_PREFIX_2 "%s: Requested PROCEEDING-Indication for %s\n",
4720
if (i->ntmode) pbx_capi_signal_progress(c, NULL);
4722
case AST_CONTROL_HOLD:
4723
cc_verbose(3, 1, VERBOSE_PREFIX_2 "%s: Requested HOLD-Indication for %s\n",
4725
if (i->doholdtype != CC_HOLDTYPE_LOCAL) {
4726
ret = pbx_capi_hold(c, NULL);
4729
case AST_CONTROL_UNHOLD:
4730
cc_verbose(3, 1, VERBOSE_PREFIX_2 "%s: Requested UNHOLD-Indication for %s\n",
4732
if (i->doholdtype != CC_HOLDTYPE_LOCAL) {
4733
ret = pbx_capi_retrieve(c, NULL);
4736
case -1: /* stop indications */
4737
cc_verbose(3, 1, VERBOSE_PREFIX_2 "%s: Requested Indication-STOP for %s\n",
4739
if ((i->isdnstate & CAPI_ISDN_STATE_HOLD))
4740
pbx_capi_retrieve(c, NULL);
4743
cc_verbose(3, 1, VERBOSE_PREFIX_2 "%s: Requested unknown Indication %d for %s\n",
4744
i->vname, condition, c->name);
4747
cc_mutex_unlock(&i->lock);
4752
* PBX wants to know the state for a specific device
4754
static int pbx_capi_devicestate(void *data)
4756
int res = AST_DEVICE_UNKNOWN;
4759
cc_verbose(3, 1, VERBOSE_PREFIX_2 "No data for capi_devicestate\n");
4763
cc_verbose(3, 1, VERBOSE_PREFIX_4 "CAPI devicestate requested for %s\n",
4769
static void capi_do_channel_task(void)
4771
if (chan_for_task == NULL)
4774
switch(channel_task) {
4775
case CAPI_CHANNEL_TASK_HANGUP:
4776
/* deferred (out of lock) hangup */
4777
ast_hangup(chan_for_task);
4779
case CAPI_CHANNEL_TASK_SOFTHANGUP:
4780
/* deferred (out of lock) soft-hangup */
4781
ast_softhangup(chan_for_task, AST_SOFTHANGUP_DEV);
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);
4788
ast_hangup(chan_for_task);
4794
chan_for_task = NULL;
4795
channel_task = CAPI_CHANNEL_TASK_NONE;
4799
* module stuff, monitor...
4801
static void *capidev_loop(void *data)
4806
for (/* for ever */;;) {
4807
switch(Info = capidev_check_wait_get_cmsg(&monCMSG)) {
4809
capidev_handle_msg(&monCMSG);
4810
capi_do_channel_task();
4813
/* CAPI queue is empty */
4816
/* The application ID is no longer valid.
4817
* This error is fatal, and "chan_capi"
4820
cc_log(LOG_ERROR, "CAPI reports application ID no longer valid, PANIC\n");
4823
/* something is wrong! */
4835
static void capi_gains(struct cc_capi_gains *g, float rxgain, float txgain)
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);
4845
x = (int)(((float)capiALAW2INT[i]) * rxgain);
4851
if (capi_capability == AST_FORMAT_ULAW) {
4852
g->rxgains[i] = capi_int2ulaw(x);
4854
g->rxgains[i] = capi_int2alaw(x);
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);
4864
x = (int)(((float)capiALAW2INT[i]) * txgain);
4870
if (capi_capability == AST_FORMAT_ULAW) {
4871
g->txgains[i] = capi_int2ulaw(x);
4873
g->txgains[i] = capi_int2alaw(x);
4880
* create new interface
4882
int mkif(struct cc_capi_conf *conf)
4884
struct capi_pvt *tmp;
4888
for (i = 0; i <= conf->devices; i++) {
4889
tmp = malloc(sizeof(struct capi_pvt));
4893
memset(tmp, 0, sizeof(struct capi_pvt));
4898
cc_mutex_init(&tmp->lock);
4899
ast_cond_init(&tmp->event_trigger, NULL);
4902
snprintf(tmp->name, sizeof(tmp->name) - 1, "%s-pseudo-D", conf->name);
4903
tmp->channeltype = CAPI_CHANNELTYPE_D;
4905
cc_copy_string(tmp->name, conf->name, sizeof(tmp->name));
4906
tmp->channeltype = CAPI_CHANNELTYPE_B;
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));
4916
unit = atoi(conf->controllerstr);
4917
/* There is no reason not to
4918
* allow controller 0 !
4920
* Hide problem from user:
4923
/* The ISDN4BSD kernel will modulo
4924
* the controller number by
4925
* "capi_num_controllers", so this
4926
* is equivalent to "0":
4928
unit = capi_num_controllers;
4931
/* always range check user input */
4932
if (unit > CAPI_MAX_CONTROLLERS)
4933
unit = CAPI_MAX_CONTROLLERS;
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;
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;
4954
tmp->smoother = ast_smoother_new(CAPI_MAX_B3_BLOCK_SIZE);
4956
tmp->rxgain = conf->rxgain;
4957
tmp->txgain = conf->txgain;
4958
capi_gains(&tmp->g, conf->rxgain, conf->txgain);
4960
tmp->doDTMF = conf->softdtmf;
4961
tmp->capability = conf->capability;
4963
tmp->next = iflist; /* prepend */
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);
4974
* eval supported services
4976
static void supported_sservices(struct cc_capi_controller *cp)
4978
MESSAGE_EXCHANGE_ERROR error;
4981
unsigned char fac[20];
4982
unsigned int services;
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;
4989
FACILITY_REQ_FACILITYREQUESTPARAMETER(&CMSG) = (_cstruct)&fac;
4990
_capi_put_cmsg(&CMSG);
4995
for (/* for ever */;;) {
4996
error = capi20_waitformessage(capi_ApplID, &tv);
4997
error = capi_get_cmsg(&CMSG2, capi_ApplID);
4999
if (IS_FACILITY_CONF(&CMSG2)) {
5000
cc_verbose(5, 0, VERBOSE_PREFIX_4 "FACILITY_CONF INFO = %#x\n",
5001
FACILITY_CONF_INFO(&CMSG2));
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));
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]);
5019
services = read_capi_dword(&(FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[6]));
5020
cc_verbose(3, 0, VERBOSE_PREFIX_4 "supplementary services : 0x%08x\n",
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");
2441
cp->holdretrieve = 0;
2443
if (((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[6] & 2) >> 1) == 1) {
5027
cc_verbose(3, 0, "HOLD/RETRIEVE ");
5029
if (services & 0x0002) {
2444
5030
cp->terminalportability = 1;
2445
if (option_verbose > 3)
2446
ast_verbose(VERBOSE_PREFIX_4 "TERMINAL PORTABILITY\n");
2448
cp->terminalportability = 0;
2450
if (((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[6] & 4) >> 2) == 1) {
5031
cc_verbose(3, 0, "TERMINAL-PORTABILITY ");
5033
if (services & 0x0004) {
2452
if (option_verbose > 3)
2453
ast_verbose(VERBOSE_PREFIX_4 "ECT\n");
2457
if (((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[6] & 8) >> 3) == 1) {
5035
cc_verbose(3, 0, "ECT ");
5037
if (services & 0x0008) {
2458
5038
cp->threePTY = 1;
2459
if (option_verbose > 3)
2460
ast_verbose(VERBOSE_PREFIX_4 "3PTY\n");
2464
if (((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[6] & 16) >> 4) == 1) {
5039
cc_verbose(3, 0, "3PTY ");
5041
if (services & 0x0010) {
2466
if (option_verbose > 3)
2467
ast_verbose(VERBOSE_PREFIX_4 "CF\n");
2471
if (((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[6] & 32) >> 5) == 1) {
5043
cc_verbose(3, 0, "CF ");
5045
if (services & 0x0020) {
2473
if (option_verbose > 3)
2474
ast_verbose(VERBOSE_PREFIX_4 "CD\n");
2478
if (((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[6] & 64) >> 6) == 1) {
5047
cc_verbose(3, 0, "CD ");
5049
if (services & 0x0040) {
2480
if (option_verbose > 3)
2481
ast_verbose(VERBOSE_PREFIX_4 "MCID\n");
2485
if (((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[6] & 128) >> 7) == 1) {
5051
cc_verbose(3, 0, "MCID ");
5053
if (services & 0x0080) {
2487
if (option_verbose > 3)
2488
ast_verbose(VERBOSE_PREFIX_4 "CCBS\n");
2492
if ((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[7] & 1) == 1) {
5055
cc_verbose(3, 0, "CCBS ");
5057
if (services & 0x0100) {
2494
if (option_verbose > 3)
2495
ast_verbose(VERBOSE_PREFIX_4 "MWI\n");
2499
if (((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[7] & 2) >> 1) == 1) {
5059
cc_verbose(3, 0, "MWI ");
5061
if (services & 0x0200) {
2501
if (option_verbose > 3)
2502
ast_verbose(VERBOSE_PREFIX_4 "CCNR\n");
2506
if (((FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[7] & 4) >> 2) == 1) {
5063
cc_verbose(3, 0, "CCNR ");
5065
if (services & 0x0400) {
2508
if (option_verbose > 3)
2509
ast_verbose(VERBOSE_PREFIX_4 "CONF\n");
2514
ast_log(LOG_NOTICE,"supplementary services info = %#x\n",(short)FACILITY_CONF_FACILITYCONFIRMATIONPARAMETER(&CMSG2)[1]);
2517
ast_log(LOG_NOTICE,"unexpected FACILITY_SELECTOR = %#x\n",FACILITY_CONF_FACILITYSELECTOR(&CMSG2));
2521
static int capi_info(int fd, int argc, char *argv[])
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);
2531
ast_mutex_unlock(&contrlock);
2533
return RESULT_SUCCESS;
2536
static int capi_do_debug(int fd, int argc, char *argv[])
2539
return RESULT_SHOWUSAGE;
5067
cc_verbose(3, 0, "CONF");
5069
cc_verbose(3, 0, "\n");
5074
* helper functions to convert conf value to string
5076
static char *show_bproto(int bproto)
5079
case CC_BPROTO_TRANSPARENT:
5081
case CC_BPROTO_FAXG3:
5088
static char *show_state(int state)
5091
case CAPI_STATE_ALERTING:
5093
case CAPI_STATE_CONNECTED:
5095
case CAPI_STATE_DISCONNECTING:
5097
case CAPI_STATE_DISCONNECTED:
5099
case CAPI_STATE_CONNECTPENDING:
5101
case CAPI_STATE_ANSWERING:
5103
case CAPI_STATE_DID:
5105
case CAPI_STATE_INCALL:
5107
case CAPI_STATE_ONHOLD:
5112
static char *show_isdnstate(unsigned int isdnstate, char *str)
5116
if (isdnstate & CAPI_ISDN_STATE_PBX)
5118
if (isdnstate & CAPI_ISDN_STATE_LI)
5120
if (isdnstate & CAPI_ISDN_STATE_B3_UP)
5122
if (isdnstate & CAPI_ISDN_STATE_B3_PEND)
5124
if (isdnstate & CAPI_ISDN_STATE_PROGRESS)
5126
if (isdnstate & CAPI_ISDN_STATE_HOLD)
5128
if (isdnstate & CAPI_ISDN_STATE_ECT)
5130
if (isdnstate & (CAPI_ISDN_STATE_SETUP | CAPI_ISDN_STATE_SETUP_ACK))
5137
* do command capi show channels
5139
static int pbxcli_capi_show_channels(int fd, int argc, char *argv[])
5147
return RESULT_SHOWUSAGE;
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");
5153
cc_mutex_lock(&iflock);
5155
for (i = iflist; i; i = i->next) {
5156
if (i->channeltype != CAPI_CHANNELTYPE_B)
5159
if ((i->state == 0) || (i->state == CAPI_STATE_DISCONNECTED))
5161
else if (i->outgoing)
5167
snprintf(b3q, sizeof(b3q), " B3q=%d", i->B3q);
5172
"%-16s %s %s %c %s %-10s 0x%02x '%s'->'%s'%s\n",
5174
i->ntmode ? "yes":"no ",
5175
show_state(i->state),
5177
show_bproto(i->bproto),
5178
show_isdnstate(i->isdnstate, i_state),
5186
cc_mutex_unlock(&iflock);
5188
return RESULT_SUCCESS;
5192
* do command capi info
5194
static int pbxcli_capi_info(int fd, int argc, char *argv[])
5199
return RESULT_SHOWUSAGE;
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);
5208
return RESULT_SUCCESS;
5214
static int pbxcli_capi_do_debug(int fd, int argc, char *argv[])
5217
return RESULT_SHOWUSAGE;
2541
5220
ast_cli(fd, "CAPI Debugging Enabled\n");
2542
5222
return RESULT_SUCCESS;
2545
static int capi_no_debug(int fd, int argc, char *argv[])
5228
static int pbxcli_capi_no_debug(int fd, int argc, char *argv[])
2548
5231
return RESULT_SHOWUSAGE;
2550
5234
ast_cli(fd, "CAPI Debugging Disabled\n");
2551
5236
return RESULT_SUCCESS;
2554
5242
static char info_usage[] =
2555
5243
"Usage: capi info\n"
5244
" Show info about B channels on controllers.\n";
5246
static char show_channels_usage[] =
5247
"Usage: capi show channels\n"
2556
5248
" Show info about B channels.\n";
2558
5250
static char debug_usage[] =