New version of capiconn.
This commit is contained in:
parent
7f5bd829f3
commit
c66178810c
|
@ -10,6 +10,9 @@
|
||||||
* 2 of the License, or (at your option) any later version.
|
* 2 of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* $Log$
|
* $Log$
|
||||||
|
* Revision 1.8 2004/01/16 15:27:13 calle
|
||||||
|
* remove several warnings.
|
||||||
|
*
|
||||||
* Revision 1.7 2002/05/03 11:57:49 calle
|
* Revision 1.7 2002/05/03 11:57:49 calle
|
||||||
* Bugfix of Bugfix.
|
* Bugfix of Bugfix.
|
||||||
*
|
*
|
||||||
|
@ -34,15 +37,11 @@
|
||||||
* Plugin for pppd to support PPP over CAPI2.0.
|
* Plugin for pppd to support PPP over CAPI2.0.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h> /* snprintf */
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "capiconn.h"
|
#include "capiconn.h"
|
||||||
|
|
||||||
static char *revision = "$Revision$";
|
static char *revision = "$Revision$";
|
||||||
|
|
||||||
/* xxxxxxxxxxxxxxxxxx */
|
|
||||||
static _cmsg cmdcmsg;
|
static _cmsg cmdcmsg;
|
||||||
static _cmsg cmsg;
|
static _cmsg cmsg;
|
||||||
|
|
||||||
|
@ -52,6 +51,37 @@ static _cmsg cmsg;
|
||||||
#define CAPI_MAXDATAWINDOW 8
|
#define CAPI_MAXDATAWINDOW 8
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* -------- util functions ------------------------------------------- */
|
||||||
|
|
||||||
|
static inline int capimsg_addu8(void *m, int off, _cbyte val)
|
||||||
|
{
|
||||||
|
((_cbyte *)m)[off] = val;
|
||||||
|
return off+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int capimsg_addu16(void *m, int off, _cword val)
|
||||||
|
{
|
||||||
|
((_cbyte *)m)[off] = val & 0xff;
|
||||||
|
((_cbyte *)m)[off+1] = (val >> 8) & 0xff;
|
||||||
|
return off+2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int capimsg_addu32(void *m, int off, _cdword val)
|
||||||
|
{
|
||||||
|
((_cbyte *)m)[off] = val & 0xff;
|
||||||
|
((_cbyte *)m)[off+1] = (val >> 8) & 0xff;
|
||||||
|
((_cbyte *)m)[off+2] = (val >> 16) & 0xff;
|
||||||
|
((_cbyte *)m)[off+3] = (val >> 24) & 0xff;
|
||||||
|
return off+4;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int capimsg_addcstruct(void *m, int off, _cbyte len, _cbyte *val)
|
||||||
|
{
|
||||||
|
if (len == 0 || val == 0) return capimsg_addu8(m, off, 0);
|
||||||
|
memcpy(m+off, val, len);
|
||||||
|
return off+len;
|
||||||
|
}
|
||||||
|
|
||||||
/* -------- type definitions ----------------------------------------- */
|
/* -------- type definitions ----------------------------------------- */
|
||||||
|
|
||||||
struct capiconn_context {
|
struct capiconn_context {
|
||||||
|
@ -105,8 +135,7 @@ struct capi_contr {
|
||||||
|
|
||||||
unsigned incoming:1,
|
unsigned incoming:1,
|
||||||
disconnecting:1,
|
disconnecting:1,
|
||||||
localdisconnect:1,
|
localdisconnect:1;
|
||||||
callednumbercomplete:1;
|
|
||||||
|
|
||||||
_cword disconnectreason;
|
_cword disconnectreason;
|
||||||
_cword disconnectreason_b3;
|
_cword disconnectreason_b3;
|
||||||
|
@ -131,6 +160,7 @@ struct capi_contr {
|
||||||
} *ackqueue;
|
} *ackqueue;
|
||||||
int ackqueuelen;
|
int ackqueuelen;
|
||||||
} *nccip;
|
} *nccip;
|
||||||
|
void *userdata;
|
||||||
} *connections;
|
} *connections;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -426,15 +456,16 @@ static int set_conninfo1a(capiconn_context *ctx,
|
||||||
if (callednumber[0] & 0x80) {
|
if (callednumber[0] & 0x80) {
|
||||||
memcpy(p->callednumber+1, callednumber, len);
|
memcpy(p->callednumber+1, callednumber, len);
|
||||||
p->callednumber[0] = len;
|
p->callednumber[0] = len;
|
||||||
p->callednumber[len+1] = 0;
|
p->callednumber[len+1] = 0;
|
||||||
} else {
|
} else {
|
||||||
memcpy(p->callednumber+2, callednumber, len);
|
memcpy(p->callednumber+2, callednumber, len);
|
||||||
p->callednumber[0] = len+1;
|
p->callednumber[0] = len+1;
|
||||||
p->callednumber[1] = 0x81;
|
p->callednumber[1] = 0x81;
|
||||||
p->callednumber[len+2] = 0;
|
p->callednumber[len+2] = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
p->callednumber[0] = 0;
|
p->callednumber[0] = 0;
|
||||||
|
p->callednumber[1] = 0;
|
||||||
}
|
}
|
||||||
if ((p->callingnumber = (*cb->malloc)(128)) == 0)
|
if ((p->callingnumber = (*cb->malloc)(128)) == 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -443,10 +474,13 @@ static int set_conninfo1a(capiconn_context *ctx,
|
||||||
memcpy(p->callingnumber+3, callingnumber, len);
|
memcpy(p->callingnumber+3, callingnumber, len);
|
||||||
p->callingnumber[0] = len+2;
|
p->callingnumber[0] = len+2;
|
||||||
p->callingnumber[1] = 0x00;
|
p->callingnumber[1] = 0x00;
|
||||||
p->callingnumber[2] = 0x80;
|
p->callingnumber[2] = 0x80;
|
||||||
p->callingnumber[len+3] = 0;
|
p->callingnumber[len+3] = 0;
|
||||||
} else {
|
} else {
|
||||||
p->callingnumber[0] = 0;
|
p->callingnumber[0] = 2;
|
||||||
|
p->callingnumber[1] = 0x00;
|
||||||
|
p->callingnumber[2] = 0x80;
|
||||||
|
p->callingnumber[3] = 0;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
fail:
|
fail:
|
||||||
|
@ -465,21 +499,33 @@ static int set_conninfo1b(capiconn_context *ctx,
|
||||||
|
|
||||||
p->cipvalue = cipvalue;
|
p->cipvalue = cipvalue;
|
||||||
|
|
||||||
if ((p->callednumber = (*cb->malloc)(128)) == 0)
|
if ((p->callednumber = (*cb->malloc)(128)) == 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
len = callednumber[0];
|
if (callednumber && callednumber[0] >= 2) {
|
||||||
memcpy(p->callednumber, callednumber, len+1);
|
len = callednumber[0];
|
||||||
p->callednumber[len+1] = 0;
|
memcpy(p->callednumber, callednumber, len+1);
|
||||||
|
p->callednumber[len+1] = 0;
|
||||||
if ((p->callingnumber = (*cb->malloc)(128)) == 0)
|
} else {
|
||||||
goto fail;
|
p->callednumber[0] = 1;
|
||||||
len = callingnumber[0];
|
p->callednumber[1] = 0x81;
|
||||||
memcpy(p->callingnumber, callingnumber, len+1);
|
p->callednumber[2] = 0;
|
||||||
p->callingnumber[len+1] = 0;
|
}
|
||||||
return 0;
|
if ((p->callingnumber = (*cb->malloc)(128)) == 0)
|
||||||
|
goto fail;
|
||||||
|
if (callingnumber && callingnumber[0] >= 3) {
|
||||||
|
len = callingnumber[0];
|
||||||
|
memcpy(p->callingnumber, callingnumber, len+1);
|
||||||
|
p->callingnumber[len+1] = 0;
|
||||||
|
} else {
|
||||||
|
p->callingnumber[0] = 2;
|
||||||
|
p->callingnumber[1] = 0x00;
|
||||||
|
p->callingnumber[2] = 0x80;
|
||||||
|
p->callingnumber[3] = 0;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
fail:
|
fail:
|
||||||
clr_conninfo1(ctx, p);
|
clr_conninfo1(ctx, p);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void extend_callednumber(capiconn_context *ctx, capi_conninfo *p,
|
static void extend_callednumber(capiconn_context *ctx, capi_conninfo *p,
|
||||||
|
@ -570,7 +616,7 @@ static int capi_add_ack(capi_ncci *nccip,
|
||||||
ncci_datahandle_queue *n, **pp;
|
ncci_datahandle_queue *n, **pp;
|
||||||
|
|
||||||
if (nccip->ackqueuelen >= CAPI_MAXDATAWINDOW)
|
if (nccip->ackqueuelen >= CAPI_MAXDATAWINDOW)
|
||||||
return 0;
|
return 1;
|
||||||
n = (ncci_datahandle_queue *)
|
n = (ncci_datahandle_queue *)
|
||||||
(*cb->malloc)(sizeof(ncci_datahandle_queue));
|
(*cb->malloc)(sizeof(ncci_datahandle_queue));
|
||||||
if (!n) {
|
if (!n) {
|
||||||
|
@ -603,6 +649,7 @@ static unsigned char *capi_del_ack(capi_ncci *nccip, _cword datahandle)
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
(*cb->errmsg)("datahandle %u not found", datahandle);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -948,6 +995,8 @@ static void handle_controller(capiconn_context *ctx, _cmsg * cmsg)
|
||||||
cmsg->adr.adrController);
|
cmsg->adr.adrController);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned char SendingComplete[5] = { 4, 1, 0, 0, 0 };
|
||||||
|
|
||||||
static void check_incoming_complete(capi_connection *plcip)
|
static void check_incoming_complete(capi_connection *plcip)
|
||||||
{
|
{
|
||||||
capi_contr *card = plcip->contr;
|
capi_contr *card = plcip->contr;
|
||||||
|
@ -971,12 +1020,6 @@ static void check_incoming_complete(capi_connection *plcip)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (plcip->callednumbercomplete)
|
|
||||||
return;
|
|
||||||
|
|
||||||
plcip->callednumbercomplete = 1;
|
|
||||||
|
|
||||||
if (*cb->incoming)
|
if (*cb->incoming)
|
||||||
(*cb->incoming)(plcip,
|
(*cb->incoming)(plcip,
|
||||||
plcip->contr->contrnr,
|
plcip->contr->contrnr,
|
||||||
|
@ -993,7 +1036,8 @@ static void check_incoming_complete(capi_connection *plcip)
|
||||||
0, /* BChannelinformation */
|
0, /* BChannelinformation */
|
||||||
0, /* Keypadfacility */
|
0, /* Keypadfacility */
|
||||||
0, /* Useruserdata */
|
0, /* Useruserdata */
|
||||||
0 /* Facilitydataarray */
|
0, /* Facilitydataarray */
|
||||||
|
SendingComplete
|
||||||
);
|
);
|
||||||
plcip->msgid = cmsg.Messagenumber;
|
plcip->msgid = cmsg.Messagenumber;
|
||||||
send_message(card, &cmsg);
|
send_message(card, &cmsg);
|
||||||
|
@ -1023,8 +1067,8 @@ static void handle_incoming_call(capi_contr * card, _cmsg * cmsg)
|
||||||
(*cb->debugmsg)("incoming call contr=%d cip=%d %s -> %s",
|
(*cb->debugmsg)("incoming call contr=%d cip=%d %s -> %s",
|
||||||
card->contrnr,
|
card->contrnr,
|
||||||
cmsg->CIPValue,
|
cmsg->CIPValue,
|
||||||
plcip->conninfo.callingnumber + 3,
|
plcip->conninfo.callingnumber+2,
|
||||||
plcip->conninfo.callednumber + 2);
|
plcip->conninfo.callednumber+3);
|
||||||
|
|
||||||
if (cb->incoming == 0)
|
if (cb->incoming == 0)
|
||||||
goto ignore;
|
goto ignore;
|
||||||
|
@ -1120,24 +1164,17 @@ static int handle_callednumber_info(capi_connection *plcip, _cmsg *cmsg)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int handle_cause_info(capi_connection *plcip, _cmsg *cmsg)
|
static int handle_dtmf_info(capi_connection *plcip, _cmsg *cmsg)
|
||||||
{
|
{
|
||||||
capiconn_context *ctx = plcip->ctx;
|
capiconn_context *ctx = plcip->ctx;
|
||||||
capiconn_callbacks *cb = ctx->cb;
|
capiconn_callbacks *cb = ctx->cb;
|
||||||
|
|
||||||
unsigned char *p = cmsg->InfoElement;
|
if (cmsg->InfoNumber == 0x002c) {
|
||||||
if (cmsg->InfoNumber == 0x0008) {
|
if (cb->dtmf_received)
|
||||||
char buf[128];
|
(*cb->dtmf_received)(plcip,
|
||||||
char *s, *end;
|
cmsg->InfoElement+1,
|
||||||
int i;
|
cmsg->InfoElement[0]);
|
||||||
s = buf; end = s + sizeof(buf)-1;
|
return 1;
|
||||||
*end = 0;
|
|
||||||
for (i=0; i < p[0]; i++) {
|
|
||||||
snprintf(s, end-s, " %02x", p[i+1]);
|
|
||||||
s += strlen(s);
|
|
||||||
}
|
|
||||||
(*cb->debugmsg)("cause bytes for plci 0x%x:%s", cmsg->adr.adrPLCI, buf);
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1262,7 +1299,7 @@ static void handle_plci(capiconn_context *ctx, _cmsg * cmsg)
|
||||||
} else if (handle_callednumber_info(plcip, cmsg)) {
|
} else if (handle_callednumber_info(plcip, cmsg)) {
|
||||||
capi_cmsg_answer(cmsg);
|
capi_cmsg_answer(cmsg);
|
||||||
send_message(card, cmsg);
|
send_message(card, cmsg);
|
||||||
} else if (handle_cause_info(plcip, cmsg)) {
|
} else if (handle_dtmf_info(plcip, cmsg)) {
|
||||||
capi_cmsg_answer(cmsg);
|
capi_cmsg_answer(cmsg);
|
||||||
send_message(card, cmsg);
|
send_message(card, cmsg);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1276,6 +1313,16 @@ static void handle_plci(capiconn_context *ctx, _cmsg * cmsg)
|
||||||
case CAPI_SELECT_B_PROTOCOL_CONF: /* plci */
|
case CAPI_SELECT_B_PROTOCOL_CONF: /* plci */
|
||||||
goto ignored;
|
goto ignored;
|
||||||
case CAPI_FACILITY_IND: /* Controller/plci/ncci */
|
case CAPI_FACILITY_IND: /* Controller/plci/ncci */
|
||||||
|
if (!(plcip = find_plci_by_plci(card, cmsg->adr.adrPLCI)))
|
||||||
|
goto notfound;
|
||||||
|
if (cmsg->FacilitySelector == 1) { /* DTMF */
|
||||||
|
(*cb->dtmf_received)(plcip,
|
||||||
|
cmsg->FacilityIndicationParameter+1,
|
||||||
|
cmsg->FacilityIndicationParameter[0]);
|
||||||
|
capi_cmsg_answer(cmsg);
|
||||||
|
send_message(card, cmsg);
|
||||||
|
break;
|
||||||
|
}
|
||||||
goto ignored;
|
goto ignored;
|
||||||
case CAPI_FACILITY_CONF: /* Controller/plci/ncci */
|
case CAPI_FACILITY_CONF: /* Controller/plci/ncci */
|
||||||
goto ignored;
|
goto ignored;
|
||||||
|
@ -1448,8 +1495,40 @@ static void handle_ncci(capiconn_context *ctx, _cmsg * cmsg)
|
||||||
|
|
||||||
case CAPI_FACILITY_IND: /* Controller/plci/ncci */
|
case CAPI_FACILITY_IND: /* Controller/plci/ncci */
|
||||||
goto ignored;
|
goto ignored;
|
||||||
|
|
||||||
case CAPI_FACILITY_CONF: /* Controller/plci/ncci */
|
case CAPI_FACILITY_CONF: /* Controller/plci/ncci */
|
||||||
goto ignored;
|
if (!(nccip = find_ncci(card, cmsg->adr.adrNCCI)))
|
||||||
|
goto notfound;
|
||||||
|
if (cmsg->Info) {
|
||||||
|
(*cb->infomsg)("%s info 0x%x (%s) for ncci 0x%x",
|
||||||
|
capi_cmd2str(cmsg->Command, cmsg->Subcommand),
|
||||||
|
cmsg->Info, capi_info2str(cmsg->Info),
|
||||||
|
cmsg->adr.adrNCCI);
|
||||||
|
} else if ( cmsg->FacilitySelector == 1
|
||||||
|
&& cmsg->FacilityConfirmationParameter[0] > 0
|
||||||
|
&& cmsg->FacilityConfirmationParameter[1]) {
|
||||||
|
switch (cmsg->FacilityConfirmationParameter[1]) {
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
(*cb->infomsg)("%s incorrect DTMF digit for ncci 0x%x",
|
||||||
|
capi_cmd2str(cmsg->Command, cmsg->Subcommand),
|
||||||
|
cmsg->adr.adrNCCI);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
(*cb->infomsg)("%s Unknown DTMF request for ncci 0x%x",
|
||||||
|
capi_cmd2str(cmsg->Command, cmsg->Subcommand),
|
||||||
|
cmsg->adr.adrNCCI);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
(*cb->infomsg)("%s DTMF errcode %d for ncci 0x%x",
|
||||||
|
capi_cmd2str(cmsg->Command, cmsg->Subcommand),
|
||||||
|
cmsg->FacilityConfirmationParameter[1],
|
||||||
|
cmsg->adr.adrNCCI);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
(*cb->errmsg)("capidrv-%d: got %s for ncci 0x%x ???",
|
(*cb->errmsg)("capidrv-%d: got %s for ncci 0x%x ???",
|
||||||
|
@ -1771,6 +1850,53 @@ int capiconn_disconnect(capi_connection *plcip, _cstruct ncpi)
|
||||||
|
|
||||||
static _cmsg sendcmsg;
|
static _cmsg sendcmsg;
|
||||||
|
|
||||||
|
|
||||||
|
// #define TX_STATS
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef TX_STATS
|
||||||
|
|
||||||
|
|
||||||
|
static FILE *dump_open(void)
|
||||||
|
{
|
||||||
|
struct stat sb;
|
||||||
|
|
||||||
|
if (0 == stat("/var/tmp/voipd.txt", &sb)
|
||||||
|
&& sb.st_size > 60000) {
|
||||||
|
unlink("/var/tmp/voipd.txt");
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *fp = fopen("/var/tmp/voipd.txt", "a");
|
||||||
|
|
||||||
|
return fp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void ncci_dump(capi_ncci *nccip, char *header)
|
||||||
|
{
|
||||||
|
FILE *fp = dump_open();
|
||||||
|
|
||||||
|
if (fp) {
|
||||||
|
time_t t = time(0);
|
||||||
|
fprintf(fp, "\n%02u:%02u:%02u %s\n", t / (60*60), (t / 60) % 60, t % 60, header);
|
||||||
|
// txstat_dump(&nccip->txstats, fp);
|
||||||
|
// fprintf(fp, "Tx Packet Time Distribution:\n");
|
||||||
|
// timedist_dump(&nccip->txpackettdist, fp);
|
||||||
|
// fprintf(fp, "Tx DATA B3 CONF Time Distribution:\n");
|
||||||
|
// timedist_dump(&nccip->txconftdist, fp);
|
||||||
|
// fprintf(fp, "Tx Underrun Time Distribution:\n");
|
||||||
|
// timedist_dump(&nccip->txUnderruntdist, fp);
|
||||||
|
|
||||||
|
rtp_stats_display_fp(ortp_get_global_stats(), "RTP Global", fp);
|
||||||
|
|
||||||
|
// fprintf(fp, "*** Mediastraemer Fifos:\n");
|
||||||
|
// ms_fifo_dump(fp);
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
int capiconn_send(capi_connection *plcip,
|
int capiconn_send(capi_connection *plcip,
|
||||||
unsigned char *data,
|
unsigned char *data,
|
||||||
unsigned len)
|
unsigned len)
|
||||||
|
@ -1786,6 +1912,25 @@ int capiconn_send(capi_connection *plcip,
|
||||||
if (!nccip || nccip->state != ST_NCCI_ACTIVE)
|
if (!nccip || nccip->state != ST_NCCI_ACTIVE)
|
||||||
return CAPICONN_WRONG_STATE;
|
return CAPICONN_WRONG_STATE;
|
||||||
|
|
||||||
|
#ifdef TX_STATS
|
||||||
|
{
|
||||||
|
struct timeval tv;
|
||||||
|
struct timezone tz;
|
||||||
|
unsigned tstamp;
|
||||||
|
static unsigned next_dump_tstamp = 0;
|
||||||
|
|
||||||
|
tstamp = gettimeofday(&tv, &tz);
|
||||||
|
tstamp = tv.tv_sec * 1000 + (tv.tv_usec/1000);
|
||||||
|
// timedist_event(&nccip->txpackettdist, tstamp);
|
||||||
|
|
||||||
|
if (tstamp >= next_dump_tstamp) {
|
||||||
|
next_dump_tstamp = tstamp + 120*1000;
|
||||||
|
ncci_dump(nccip, "ncci periodic");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // TX_STATS
|
||||||
|
|
||||||
|
|
||||||
datahandle = nccip->datahandle;
|
datahandle = nccip->datahandle;
|
||||||
capi_fill_DATA_B3_REQ(&sendcmsg, ctx->appid, card->msgid++,
|
capi_fill_DATA_B3_REQ(&sendcmsg, ctx->appid, card->msgid++,
|
||||||
nccip->ncci, /* adr */
|
nccip->ncci, /* adr */
|
||||||
|
@ -1795,16 +1940,91 @@ int capiconn_send(capi_connection *plcip,
|
||||||
0 /* Flags */
|
0 /* Flags */
|
||||||
);
|
);
|
||||||
|
|
||||||
if (capi_add_ack(nccip, datahandle, data) < 0)
|
if (capi_add_ack(nccip, datahandle, data) != 0)
|
||||||
return CAPICONN_NOT_SENT;
|
return CAPICONN_NOT_SENT;
|
||||||
|
|
||||||
capi_cmsg2message(&sendcmsg, sendcmsg.buf);
|
capi_cmsg2message(&sendcmsg, sendcmsg.buf);
|
||||||
(*cb->capi_put_message) (ctx->appid, sendcmsg.buf);
|
if((*cb->capi_put_message) (ctx->appid, sendcmsg.buf) < 0) {
|
||||||
|
capi_del_ack(nccip, datahandle);
|
||||||
|
return CAPICONN_NOT_SENT;
|
||||||
|
}
|
||||||
nccip->datahandle++;
|
nccip->datahandle++;
|
||||||
ctx->nsentdatapkt++;
|
ctx->nsentdatapkt++;
|
||||||
return CAPICONN_OK;
|
return CAPICONN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int capiconn_dtmf_setstate(capi_connection *plcip, int on)
|
||||||
|
{
|
||||||
|
_cbyte fparam[32];
|
||||||
|
int off;
|
||||||
|
capi_contr *card = plcip->contr;
|
||||||
|
capiconn_context *ctx = card->ctx;
|
||||||
|
capiconn_callbacks *cb = ctx->cb;
|
||||||
|
|
||||||
|
capi_ncci *nccip;
|
||||||
|
|
||||||
|
nccip = plcip->nccip;
|
||||||
|
if (!nccip || nccip->state != ST_NCCI_ACTIVE)
|
||||||
|
return CAPICONN_WRONG_STATE;
|
||||||
|
|
||||||
|
if (cb->dtmf_received == 0)
|
||||||
|
return CAPICONN_NOT_SUPPORTED;
|
||||||
|
|
||||||
|
capi_cmsg_header(&sendcmsg, ctx->appid,
|
||||||
|
CAPI_FACILITY, CAPI_REQ, card->msgid++, nccip->ncci);
|
||||||
|
sendcmsg.FacilitySelector = 1;
|
||||||
|
off = 1;
|
||||||
|
off = capimsg_addu16(fparam, off, on ? 1 : 2); /* Function */
|
||||||
|
off = capimsg_addu16(fparam, off, 40); /* Tone-duration */
|
||||||
|
off = capimsg_addu16(fparam, off, 40); /* Gap-dureation */
|
||||||
|
off = capimsg_addcstruct(fparam, off, 0, 0); /* DTMF-digits */
|
||||||
|
off = capimsg_addcstruct(fparam, off, 0, 0); /* DTMF-characteristics */
|
||||||
|
fparam[0] = off;
|
||||||
|
sendcmsg.FacilityRequestParameter = fparam;
|
||||||
|
capi_cmsg2message(&sendcmsg, sendcmsg.buf);
|
||||||
|
(*cb->capi_put_message) (ctx->appid, sendcmsg.buf);
|
||||||
|
return CAPICONN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
int capiconn_dtmf_send(capi_connection *plcip, char *digits)
|
||||||
|
{
|
||||||
|
_cbyte fparam[256];
|
||||||
|
int off;
|
||||||
|
capi_contr *card = plcip->contr;
|
||||||
|
capiconn_context *ctx = card->ctx;
|
||||||
|
capiconn_callbacks *cb = ctx->cb;
|
||||||
|
|
||||||
|
capi_ncci *nccip;
|
||||||
|
|
||||||
|
nccip = plcip->nccip;
|
||||||
|
if (!nccip || nccip->state != ST_NCCI_ACTIVE)
|
||||||
|
return CAPICONN_WRONG_STATE;
|
||||||
|
|
||||||
|
capi_cmsg_header(&sendcmsg, ctx->appid,
|
||||||
|
CAPI_FACILITY, CAPI_REQ, card->msgid++, nccip->ncci);
|
||||||
|
sendcmsg.FacilitySelector = 1;
|
||||||
|
off = 1;
|
||||||
|
off = capimsg_addu16(fparam, off, 4); /* Function */
|
||||||
|
off = capimsg_addu16(fparam, off, 40); /* Tone-duration */
|
||||||
|
off = capimsg_addu16(fparam, off, 40); /* Gap-dureation */
|
||||||
|
off = capimsg_addcstruct(fparam, off, strlen(digits), digits);
|
||||||
|
off = capimsg_addcstruct(fparam, off, 0, 0); /* DTMF-characteristics */
|
||||||
|
fparam[0] = off;
|
||||||
|
sendcmsg.FacilityRequestParameter = fparam;
|
||||||
|
capi_cmsg2message(&sendcmsg, sendcmsg.buf);
|
||||||
|
(*cb->capi_put_message) (ctx->appid, sendcmsg.buf);
|
||||||
|
return CAPICONN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void capiconn_set_userdata(capi_connection *plcip, void *userdata)
|
||||||
|
{
|
||||||
|
plcip->userdata = userdata;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *capiconn_get_userdata(capi_connection *plcip)
|
||||||
|
{
|
||||||
|
return plcip->userdata;
|
||||||
|
}
|
||||||
|
|
||||||
/* -------- listen handling ------------------------------------------ */
|
/* -------- listen handling ------------------------------------------ */
|
||||||
|
|
||||||
|
@ -1813,7 +2033,6 @@ static void send_listen(capi_contr *card)
|
||||||
capiconn_context *ctx = card->ctx;
|
capiconn_context *ctx = card->ctx;
|
||||||
|
|
||||||
card->infomask = 0;
|
card->infomask = 0;
|
||||||
card->infomask |= (1<<0); /* cause information */
|
|
||||||
card->infomask |= (1<<2); /* Display */
|
card->infomask |= (1<<2); /* Display */
|
||||||
card->infomask |= (1<<6); /* Charge Info */
|
card->infomask |= (1<<6); /* Charge Info */
|
||||||
if (card->ddilen) card->infomask |= (1<<7); /* Called Party Number */
|
if (card->ddilen) card->infomask |= (1<<7); /* Called Party Number */
|
||||||
|
|
|
@ -10,6 +10,11 @@
|
||||||
* 2 of the License, or (at your option) any later version.
|
* 2 of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* $Log$
|
* $Log$
|
||||||
|
* Revision 1.3 2001/01/25 14:45:41 calle
|
||||||
|
* - listen always (for info messages)
|
||||||
|
* - show versions on startup
|
||||||
|
* - wait for capifs if needed
|
||||||
|
*
|
||||||
* Revision 1.2 2000/10/25 10:01:47 calle
|
* Revision 1.2 2000/10/25 10:01:47 calle
|
||||||
* (c) in all files
|
* (c) in all files
|
||||||
*
|
*
|
||||||
|
@ -17,7 +22,6 @@
|
||||||
* Plugin for pppd to support PPP over CAPI2.0.
|
* Plugin for pppd to support PPP over CAPI2.0.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __CAPICONN_H__
|
#ifndef __CAPICONN_H__
|
||||||
#define __CAPICONN_H__
|
#define __CAPICONN_H__
|
||||||
|
|
||||||
|
@ -60,6 +64,7 @@
|
||||||
#define CAPICONN_OK 0
|
#define CAPICONN_OK 0
|
||||||
#define CAPICONN_NO_CONTROLLER -1
|
#define CAPICONN_NO_CONTROLLER -1
|
||||||
#define CAPICONN_NO_MEMORY -2
|
#define CAPICONN_NO_MEMORY -2
|
||||||
|
#define CAPICONN_NOT_SUPPORTED -3
|
||||||
#define CAPICONN_WRONG_STATE 1
|
#define CAPICONN_WRONG_STATE 1
|
||||||
#define CAPICONN_NOT_SENT 2
|
#define CAPICONN_NOT_SENT 2
|
||||||
#define CAPICONN_ALREADY_DISCONNECTING 3
|
#define CAPICONN_ALREADY_DISCONNECTING 3
|
||||||
|
@ -253,10 +258,18 @@ struct capiconn_callbacks
|
||||||
void (*chargeinfo)(capi_connection *,
|
void (*chargeinfo)(capi_connection *,
|
||||||
unsigned long charge,
|
unsigned long charge,
|
||||||
int inunits);
|
int inunits);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DTMF received
|
||||||
|
*/
|
||||||
|
void (*dtmf_received)(capi_connection *,
|
||||||
|
unsigned char *data,
|
||||||
|
unsigned datalen);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* capi functions
|
* capi functions
|
||||||
*/
|
*/
|
||||||
void (*capi_put_message) (unsigned appid, unsigned char *msg);
|
int (*capi_put_message) (unsigned appid, unsigned char *msg);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* message functions
|
* message functions
|
||||||
|
@ -409,6 +422,12 @@ typedef struct capi_conninfo capi_conninfo;
|
||||||
*/
|
*/
|
||||||
capi_conninfo *capiconn_getinfo(capi_connection *p);
|
capi_conninfo *capiconn_getinfo(capi_connection *p);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* userdata per connection
|
||||||
|
*/
|
||||||
|
void capiconn_set_userdata(capi_connection *plcip, void *userdata);
|
||||||
|
void *capiconn_get_userdata(capi_connection *plcip);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* returncodes:
|
* returncodes:
|
||||||
* CAPICONN_OK - Listen request sent
|
* CAPICONN_OK - Listen request sent
|
||||||
|
@ -427,4 +446,20 @@ int capiconn_listen(capiconn_context *ctx,
|
||||||
*/
|
*/
|
||||||
int capiconn_listenstate(capiconn_context *ctx, unsigned contr);
|
int capiconn_listenstate(capiconn_context *ctx, unsigned contr);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* returncode:
|
||||||
|
* CAPICONN_OK - request sent to CAPI
|
||||||
|
* CAPICONN_NOT_SUPPORTED - DTMF not supported
|
||||||
|
* CAPICONN_WRONG_STATE - Connection is not connected
|
||||||
|
*/
|
||||||
|
int capiconn_dtmf_setstate(capi_connection *, int on);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* returncode:
|
||||||
|
* CAPICONN_OK - request sent to CAPI
|
||||||
|
* CAPICONN_NOT_SUPPORTED - DTMF not supported
|
||||||
|
* CAPICONN_WRONG_STATE - Connection is not connected
|
||||||
|
*/
|
||||||
|
int capiconn_dtmf_send(capi_connection *, char *digits);
|
||||||
|
|
||||||
#endif /* __CAPICONN_H__ */
|
#endif /* __CAPICONN_H__ */
|
||||||
|
|
|
@ -1475,6 +1475,7 @@ capiconn_callbacks callbacks = {
|
||||||
received: 0,
|
received: 0,
|
||||||
datasent: 0,
|
datasent: 0,
|
||||||
chargeinfo: chargeinfo,
|
chargeinfo: chargeinfo,
|
||||||
|
dtmf_received: 0,
|
||||||
|
|
||||||
capi_put_message: put_message,
|
capi_put_message: put_message,
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue