home *** CD-ROM | disk | FTP | other *** search
- /* 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;
- }
-
-