bintec-capi-isdnlogin/il_call.c

320 lines
8.6 KiB
C

#include "isdnlogin.h"
extern cfg_t cfg;
extern char * prog_logo;
/*******************************************************************
*
*******************************************************************/
call_t *alloc_call(void)
{
call_t *ptrCall;
ptrCall = (call_t *)malloc( sizeof(*ptrCall));
if (!ptrCall) return NULL;
memset( ptrCall, 0, sizeof(*ptrCall));
/*
* open file to transmit
*/
if (cfg.sendfile) {
ptrCall->pFilename = cfg.sendfile;
if (!(ptrCall->txfp=fopen( ptrCall->pFilename, "r"))) {
printf ("Could read from file: <%s>\n", ptrCall->pFilename);
exit ( 1 );
}
if ( cfg.verbose > 2 ) {
printf("Reading from file: <%s>\n", ptrCall->pFilename);
}
}
/* default call settings */
/* add service and controller to call */
ptrCall->active = 1;
ptrCall->ident = cfg.controller; /* controller */
ptrCall->service= cfg.service;
/* set numbers */
setCalledPartyNumber( ptrCall, cfg.rmttelno);
setCallingPartyNumber( ptrCall, cfg.loctelno, 1);
setCalledPartySubaddress( ptrCall, cfg.rmtsubaddr);
setCallingPartySubaddress( ptrCall, cfg.locsubaddr);
/* adjust protocols */
setBprotocol( ptrCall);
setLLC( ptrCall );
setAdditionalInfo( ptrCall );
return ptrCall;
}
/*******************************************************************
*
*******************************************************************/
void free_call( call_t *ptrCall )
{
if (ptrCall) {
if (ptrCall->txfp) {
fclose( ptrCall->txfp);
}
free(ptrCall);
}
}
/*******************************************************************
*
*******************************************************************/
struct userdata *setCalledPartyNumber( call_t *ptrCall,
char *szCalledPartyNumber)
{
size_t len = 0;
ptrCall->CalledPartyNumber.length = 0;
if (szCalledPartyNumber) {
len = strlen( szCalledPartyNumber);
len = min(len, CAPI1_MAXMSGLEN-1);
if (len) {
ptrCall->CalledPartyNumber.data[0] = 0x81;
memcpy( &ptrCall->CalledPartyNumber.data[1],
szCalledPartyNumber, len);
ptrCall->CalledPartyNumber.length = len+1;
}
}
return &ptrCall->CalledPartyNumber;
}
/*******************************************************************
*
*******************************************************************/
struct userdata *setCallingPartyNumber( call_t *ptrCall,
char *szCallingPartyNumber,
int lPresentation)
{
size_t len = 0;
ptrCall->CallingPartyNumber.length = 0;
if (szCallingPartyNumber) {
len = strlen( szCallingPartyNumber);
len = min(len, CAPI1_MAXMSGLEN-1);
if (len) {
ptrCall->CallingPartyNumber.data[0] = 0x01;
ptrCall->CallingPartyNumber.data[1] = lPresentation ? 0x80 : 0xa0;
memcpy( &ptrCall->CallingPartyNumber.data[2],
szCallingPartyNumber, len);
ptrCall->CallingPartyNumber.length = len+2;
}
}
return &ptrCall->CallingPartyNumber;
}
/*******************************************************************
*
*******************************************************************/
struct userdata *setCalledPartySubaddress( ptrCall, szCalledPartySubaddress)
call_t *ptrCall;
char *szCalledPartySubaddress;
{
size_t len;
ptrCall->CalledPartySubaddress.data[0] = 0x80;
if ((len = strlen(szCalledPartySubaddress))) {
memcpy( &ptrCall->CalledPartySubaddress.data[1],
szCalledPartySubaddress, len);
} else {
ptrCall->CalledPartySubaddress.data[1] = 0;
len = 1;
}
ptrCall->CalledPartySubaddress.length = len + 1;
return &ptrCall->CalledPartySubaddress;
}
/*******************************************************************
*
*******************************************************************/
struct userdata *setCallingPartySubaddress( call_t *ptrCall,
char *szCallingPartySubaddress)
{
size_t len;
ptrCall->CallingPartySubaddress.data[0] = 0x80; /* always there */
if ((len = strlen(szCallingPartySubaddress))) {
/* if subaddress suplied use it */
memcpy( &ptrCall->CallingPartySubaddress.data[1],
szCallingPartySubaddress, len);
} else {
ptrCall->CallingPartySubaddress.data[1] = 0;
len = 1;
}
ptrCall->CallingPartySubaddress.length = len + 1; /* one for the type */
return &ptrCall->CallingPartySubaddress;
}
userdata_t *setBprotocol( call_t *ptrCall)
{
userdata_t *data;
struct bprotocol *bprot;
struct b1config *b1cfg;
struct b1config_modem *b1cfg_mdm;
struct b2config *b2cfg;
struct b3config *b3cfg;
bprot = (struct bprotocol *)&ptrCall->Bprotocol;
/* set layer 1 protocol */
PUT_WORD( bprot->b1proto, ptrCall->service->layer1_mask);
/* depending on service set layer 2 protocol */
switch(ptrCall->service->hw) {
case ISDN_HDLC:
PUT_WORD( bprot->b2proto, B2X75);
break;
case FAX_G3:
PUT_WORD( bprot->b2proto, B2T30);
break;
case ISDN_V42:
PUT_WORD( bprot->b2proto, B2X75V42BIS);
break;
case V110_ASYNC:
case TRANS:
case MODEM:
default:
PUT_WORD( bprot->b2proto, B2TRANS);
break;
}
/* check for layer 2 specific settings */
switch (ptrCall->service->hw) {
case FAX_G3:
PUT_WORD( bprot->b3proto, B3T30);
break;
default:
/* layer 3 is always trans for now */
PUT_WORD( bprot->b3proto, B3TRANS);
break;
}
data = (userdata_t *)&bprot->structlen;
/* check if the service has special layer 2 config */
switch(ptrCall->service->hw) {
case V110_ASYNC:
b1cfg = (struct b1config *) data;
/* v110 specific layer 2 params */
PUT_WORD( b1cfg->rate, cfg.speed);
PUT_WORD( b1cfg->bpc, 8);
PUT_WORD( b1cfg->parity, 0);
PUT_WORD( b1cfg->stopbits, 0);
b1cfg->length = sizeof( struct b1config) - 1;
break;
case MODEM:
/* modem specific params */
b1cfg_mdm = (b1config_modem_t *) data;
PUT_WORD( b1cfg_mdm->rate, cfg.speed); /* 0 = max speed */
PUT_WORD( b1cfg_mdm->bpc, 8);
PUT_WORD( b1cfg_mdm->parity, 0);
PUT_WORD( b1cfg_mdm->stopbits, 0);
PUT_WORD( b1cfg_mdm->options, 0);
PUT_WORD( b1cfg_mdm->negotiation, 1); /* allow autoneg */
b1cfg_mdm->length = sizeof( struct b1config_modem) -1;
break;
case FAX_G3:
/* FAX group 3 params */
b1cfg = (struct b1config *) data;
PUT_WORD( b1cfg->rate, cfg.speed);
PUT_WORD( b1cfg->bpc, 0);
PUT_WORD( b1cfg->parity, 0);
PUT_WORD( b1cfg->stopbits, 0);
b1cfg->length = sizeof( struct b1config) - 1;
break;
default:
data->length = 0;
break;
}
data = (userdata_t *)&data->data[data->length];
b2cfg = (struct b2config *) data;
switch(ptrCall->service->hw) {
case ISDN_HDLC:
b2cfg->addressA = 3;
b2cfg->addressB = 1;
b2cfg->moduloMode = 8;
b2cfg->windowSize = 7;
b2cfg->xidlen = 0;
b2cfg->length = sizeof( struct b2config) - 1;
break;
default:
b2cfg->length = 0;
break;
}
data = (userdata_t *)&data->data[data->length];
/* Layer 3 always transparent */
b3cfg = (struct b3config *) data;
b3cfg->length = 0;
bprot->length = (char *)data - (char *)&bprot->length -1;
#if 0
capi_hexdump((char*) bprot, bprot->length, 16, 2);
printf("b1cfg->length=%d\n", b1cfg->length);
printf("b1cfg_mdm->length=%d\n", b1cfg_mdm->length);
printf("b2cfg->length=%d\n", b2cfg->length);
printf("bprot->length=%d\n", bprot->length);
printf("data->length=%d\n", data->length);
//printf("data->structlen=%d\n", data->structlen);
#endif
return (userdata_t *)bprot;
}
userdata_t *setLLC( call_t *ptrCall ) {
userdata_t *llc;
/* Lower Layer Compatibility */
static char llcs[] = { 0x90, 0x88, 0x90, 0x21, 0x42, 0x00, 0xbb };
llc = &ptrCall->llc;
if (ptrCall->service->rate) {
llc = (userdata_t *)&ptrCall->llc;
llcs[4] = cfg.v110_speed; /* set user rate */
memcpy(&ptrCall->llc, &llcs, sizeof(llcs));
llc->length = sizeof(llcs) - 1;
}
return llc;
}
userdata_t *setAdditionalInfo( call_t *ptrCall )
{
struct userdata *add;
struct userdata *data;
add = (struct userdata *)&ptrCall->AdditionalInfo;
data = (struct userdata *)add->data;
data->length = 0; /* b-channel */
data = (struct userdata *)&data->data[data->length];
data->length = 0; /* keypad */
data = (struct userdata *)&data->data[data->length];
memcpy(&data->data[0], prog_logo, strlen(prog_logo));
data->length = strlen(data->data); /* user user data */
data = (struct userdata *)&data->data[data->length];
data->length = 0; /* facility */
data = (struct userdata *)&data->data[data->length];
add->length = (char *)data - (char *)&add->length - 1;
return (struct userdata *)add;
}