home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
ctcoll95.zip
/
BASTELST
/
PAPI020.ZIP
/
APIINTR.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-10-06
|
10KB
|
440 lines
/* Common ISDN API C-Library Functions: interupt handler
Author: Dietmar Friede
Copyright (c) 1992 D.Friede
#include "copy"
#include "copying.doc"
*/
#include "stdio.h"
#include "types.h"
#include "api.h"
struct dlpd dlpd= {7,2048,0,0,0,0,0};
static byte nullstruct[1] = {0};
static io_state send_state= DISCON;
static io_state rcv_state= DISCON;
static long send_plci= -1, rcv_plci= -1;
static word send_ncci= 0xffff, rcv_ncci= 0xfffe;
static byte ListenErr= 0xff;
static byte CheckListen= 1;
static word rcv_ind_msg_nr;
static word api_int_mark= 0;
word SendState= 0;
word SendDir= 0;
word Ncci= 0xfffd;
byte is_api_int= 0;
dword send_err= 0, Tick= 0, LastActTime= 0;
extern byte protokoll;
extern byte PollInt;
extern byte headline;
extern char status_line[80];
byte get_prot_size(void);
int accept_con_ind(byte serv, byte serv_add, byte eaz, struct telno *num);
int api_get_message(struct msg_head **message);
int checksend(void);
int con_act_resp(word msg_nr, word plci);
int con_b3_act_resp(word msg_nr, word ncci);
int con_b3_req(word plci, byte *ncpi);
int con_b3_resp(word msg_nr, word ncci, byte reject, byte *ncpi);
int con_resp(word msg_nr, word plci, byte reject);
int dat_b3_resp(word msg_nr, word ncci, byte number);
int discon_b3_req(word ncci, byte * ncpi);
int discon_b3_resp(word msg_nr, word ncci);
int discon_req(word plci, byte cause);
int discon_resp(word msg_nr, word plci);
int inf_resp(word msg_nr, word plci);
int listen_b3_req(word plci);
int sel_b2_prot_req(word plci, byte prot, byte * dlpd);
int sel_b3_prot_req(word plci, byte prot, byte * ncpd);
void PassUp(byte * buf, word len);
void free_sendbuf(byte ind, word err);
void pass_up_info(byte *p, byte s);
void startsend(void);
void check_buf(void);
void do_api_int(void);
word
get_Ncci(void)
{
if(send_state >= IDLE)
{
SendDir= 0; /* ACTIVE */
Ncci= send_ncci;
return(SendState= send_state);
}
if(rcv_state >= IDLE)
{
SendDir= 1; /* PASSIVE */
Ncci= rcv_ncci;
return(SendState= rcv_state);
}
if(send_state >= DIAL)
return(SendState= send_state);
if(rcv_state >= CALLED)
return(SendState= rcv_state);
if(SendState==DIAL) return(DIAL);
Ncci= 0;
return(SendState= 0);
}
static word
reset_plci(long p)
{
if(p == send_plci)
{
send_plci= -1;
send_ncci= 0xffff;
send_state= DISCON;
}
if(p == rcv_plci)
{
rcv_plci= -1;
rcv_ncci= 0xfffe;
rcv_state= DISCON;
}
get_Ncci();
return (word) p;
}
static word
iserr(struct msg_head *p, int i, int m)
{
word *s;
s= (word *) &p->data[i];
if(m && *s) printf("API err %x in msg %x %x\n",*s,p->command,p->subcommand);
return(*s);
}
static void
badstate(struct msg_head *p)
{
printf("API bad state msg %x %x\n",p->command,p->subcommand);
}
void
apiint(void)
{
is_api_int++;
if(PollInt) api_int_mark++;
else do_api_int();
is_api_int--;
}
void
do_api_int(void)
{
struct msg_head *p;
word pl;
if((api_get_message(&p) == 0) && p)
{
switch(p->command)
{
case 2: /* CONNECT */
switch(p->subcommand)
{
case 1: /* CONF word plci word info */
status_line[70]='D';
pl= *((word *) p->data);
if(iserr(p,2,0))
{
if(SendState==DIAL) SendState=DISCON;
reset_plci(pl);
break;
}
send_plci= pl;
if(send_state < CONNECT) send_state= CONNECT;
break;
case 2: /* IND word plci byte contr. byte req. Serv
byte req. Serv. add. byte eaz struct caller addr. */
status_line[70]='I';
pl= *((word *) p->data);
if(accept_con_ind(p->data[3],p->data[4],p->data[5],
(struct telno *)&p->data[6]))
{
if(rcv_state < CALLED) rcv_state= CALLED;
rcv_plci= pl;
rcv_ind_msg_nr= p->msg_nr;
sel_b2_prot_req(pl,protokoll,(byte *) &dlpd);
break;
}
discon_req(reset_plci(pl),0);
}
break;
case 3: /* CONNECT ACTIVE word plci struct con_addr */
if(p->subcommand == 2)
{
pl= *((word *) p->data);
con_act_resp(p->msg_nr,pl);
if((rcv_state >= CALLED) && (rcv_plci == pl)) break;
send_plci= pl;
if(send_state < CONNECT) send_state= CONNECT;
sel_b2_prot_req(pl,protokoll,(byte *) &dlpd);
}
break;
case 4: /* DISCONNECT */
pl= *((word *) p->data);
{
int i;
for(i=30; i<80; i++) status_line[i]=' ';
}
switch(p->subcommand)
{
case 1: /* CONF word plci word info */
if(iserr(p,2,0)) reset_plci(pl);
break;
case 2: /* IND word plci word info */
if((pl==send_plci)&&(SendState==DIAL))
SendState=DISCON;
discon_resp(p->msg_nr,reset_plci(pl));
check_buf();
startsend();
}
break;
case 5: /* LISTEN */
if(p->subcommand == 1) /* CONF byte contr word info */
{
ListenErr= iserr(p,1,1);
CheckListen= 0;
}
break;
case 7: /* INFO */
switch(p->subcommand)
{
case 1: /* CONF word plci word info */
iserr(p,2,1);
break;
case 2: /* IND word plci word inf-no struc inf-element */
pass_up_info(p->data,send_state>ISDISCON);
inf_resp(p->msg_nr,*((word *) p->data));
}
break;
case 0x40: /* SELECT B2 PROTOCOL */
status_line[70]='2';
if(p->subcommand == 1) /* CONF word plci word info */
{
pl= *((word *) p->data);
if(iserr(p,2,1))
{
discon_req(reset_plci(pl),0);
break;
}
sel_b3_prot_req(pl,4,nullstruct);
}
break;
case 0x80: /* SELECT B3 PROTOCOL */
status_line[70]='3';
if(p->subcommand == 1) /* CONF word plci word info */
{
pl= *((word *) p->data);
if(iserr(p,2,1))
{
discon_req(reset_plci(pl),0);
break;
}
if(pl == send_plci) con_b3_req(pl,nullstruct);
else if(pl == rcv_plci) listen_b3_req(pl);
else badstate(p);
}
break;
case 0x81: /* LISTEN B3 */
if(p->subcommand == 1) /* CONF word plci word info */
{
pl= *((word *) p->data);
if(iserr(p,2,1))
{
discon_req(reset_plci(pl),0);
break;
}
con_resp(rcv_ind_msg_nr,pl,0);
}
break;
case 0x82: /* CONNECT B3 */
status_line[70]='C';
switch(p->subcommand)
{
case 1: /* CONF word plci word ncci word info */
pl= *((word *) p->data);
if(iserr(p,4,1))
{
discon_req(reset_plci(pl),0);
break;
}
if(pl == send_plci)
{
send_ncci= *((word *) &p->data[2]);
if(send_state < CONNECT) send_state= CONNECT;
}
else badstate(p);
break;
case 2: /* IND word ncci word plci struct ncpi */
pl= *((word *) &p->data[2]);
if(pl == rcv_plci)
{
rcv_ncci= *((word *) p->data);
con_b3_resp(p->msg_nr,rcv_ncci,0,nullstruct);
if(rcv_state < CONNECT) rcv_state= CONNECT;
}
else badstate(p);
}
break;
case 0x83: /* CONNECT B3 ACTIVE */
status_line[70]='C';
if(p->subcommand == 2) /* IND word ncci struct ncpi */
{
word n;
n= *((word *) p->data);
con_b3_act_resp(p->msg_nr,n);
if((send_plci != -1) && (n == send_ncci)&& (send_state < IDLE))
send_state= IDLE;
if((rcv_plci != -1 ) && (n == rcv_ncci) && (rcv_state < IDLE))
rcv_state= IDLE;
startsend();
if((send_state >= IDLE)&&(rcv_state >= CONNECT))
discon_b3_req(rcv_ncci,nullstruct);
}
break;
case 0x84: /* DISCONNECT B3 */
switch(p->subcommand)
{
case 1: /* CONF word ncci word info */
{
word n;
n= *((word *) p->data);
if(iserr(p,2,0))
{
if((send_plci != -1) && (n == send_ncci))
discon_req(reset_plci(send_plci),0);
else if((rcv_plci != -1) && (n == rcv_ncci))
discon_req(reset_plci(rcv_plci),0);
break;
}
if(n == send_ncci) send_state= ISDISCON;
else if(n == rcv_ncci) rcv_state= ISDISCON;
get_Ncci();
}
break;
case 2: /* IND word ncci word info struct ncpi */
{
word n;
n= *((word *) p->data);
discon_b3_resp(p->msg_nr,n);
if(n == send_ncci)
{
send_state= ISDISCON;
discon_req(reset_plci(send_plci),0);
}
else if(n == rcv_ncci)
{
rcv_state= ISDISCON;
discon_req(reset_plci(rcv_plci),0);
}
}
}
break;
case 0x86: /* DATA B3 */
LastActTime= Tick;
switch(p->subcommand)
{
case 1: /* CONF word ncci byte number word info */
status_line[71]='*';
free_sendbuf(p->data[2],iserr(p,3,0));
startsend();
break;
case 2: /* IND word ncci word data-length dword data
byte number word flags */
status_line[72]='*';
{
word ps, l;
byte far *pp;
ps= get_prot_size();
pp=(byte *) *((dword *) & p->data[4]);
l=*((word *) & p->data[2]);
PassUp(pp+ps, l-ps);
dat_b3_resp(p->msg_nr,*((word *) p->data),p->data[8]);
}
}
break;
default: badstate(p);
}
}
}
void
print_head(void)
{
extern byte far *Crtat;
extern word line;
int i,j;
for(i=0,j=line;i<80;i++,j+=2) Crtat[j]=status_line[i];
status_line[71]= status_line[72]= ' ';
}
InterruptPtr SaveTimerInt;
word DisTimeout= 10*HZ;
static dword NextCheck= 5*HZ;
void TimerTick(void)
{
is_api_int++;
if(api_int_mark)
{
do_api_int();
api_int_mark--;
}
if(++Tick > NextCheck)
{
NextCheck= Tick + HZ;
if(DisTimeout && LastActTime && (Tick > (LastActTime + DisTimeout)))
{
LastActTime= 0;
if(rcv_state > ISDISCON)
{
rcv_state= ISDISCON;
discon_b3_req(rcv_ncci,nullstruct);
}
if(send_state > ISDISCON)
{
send_state= ISDISCON;
discon_b3_req(send_ncci,nullstruct);
}
}
if(headline) print_head();
}
/* chain on old interrupt handler */
(*SaveTimerInt)();
is_api_int--;
}
word check_listen()
{
while((Tick < 450) && CheckListen);
return(ListenErr);
}
int check_con()
{
if(send_plci== -1) return 0;
discon_req(reset_plci(send_plci),0);
return 1;
}