home *** CD-ROM | disk | FTP | other *** search
- /* Common ISDN API C-Library Functions: pass down handling for papi.c
- Author: Dietmar Friede
- Copyright (c) 1992 D.Friede
- #include "copy"
- #include "copying.doc"
- */
- #include "stdio.h"
- #include <dos.h>
- #include <mem.h>
- #include "types.h"
- #include "api.h"
-
- typedef enum { EMPTY, GOT, WAIT, SENDING} bstate;
-
- struct buff
- {
- bstate state;
- word length;
- dword timeout;
- byte sbuf[2052];
- };
- static struct buff *sendbuf[4];
- static word free, head, shead, tosend;
- extern byte own_eaz;
-
- extern io_state SendState;
- extern struct telno telno;
- extern word Ncci;
- extern dword Tick, LastActTime;
- extern dword InfoMask;
- static dword DialTimeout= 0;
-
- int check_con(void);
- void init_buf(void);
- struct buff *getbuf(void);
- void freebuf(struct buff *p);
- byte get_prot_size(void);
- void set_prot(byte * p);
- word get_Ncci(void);
- void startsend(void);
- void check_buf(void);
- int con_req(byte contr, byte b_channel, dword inf_mask, byte out_serv, byte out_serv_add, byte src_eaz, struct telno * dest_addr);
- int dat_b3_req(word ncci, word dat_length, byte *data, byte number, word flags);
- word dirps(void);
- void restore(word w);
-
- void
- init_passdown(void)
- {
- int i;
- for(i=0 ; i<4; i++) sendbuf[i]= null;
- init_buf();
- free= 4;
- shead= head= tosend= 0;
- }
-
- int
- PassDown(byte *buf, word len)
- {
- register word l;
- byte ps;
- byte *p;
- struct buff *sb;
- word x;
-
- if((len == 0) || (buf ==null)) return 1;
-
- x= dirps();
- if((free == 0) || ((sb= getbuf()) == null))
- {
- check_buf();
- startsend();
- restore(x);
- return 1;
- }
- free --; tosend++;
- l= 4;
- while(sendbuf[head] && --l )
- {
- head++; head&= 0x3;
- }
- if(l == 0)
- {
- freebuf(sb);
- restore(x);
- return 1;
- }
-
- sendbuf[head++]= sb;
- head&= 0x3;
- sb->state= GOT;
- p= sb->sbuf;
-
- ps= get_prot_size();
- memcpy(p+ps,buf,len);
- sb->length= len+ps;
- sb->state= WAIT;
- sb->timeout= Tick+15*HZ;
- startsend();
- restore(x);
- return 0;
- }
-
- void
- startsend(void)
- {
- static int sema= 0;
- if(sema++) return;
-
- if(tosend)
- {
- get_Ncci();
- switch(SendState)
- {
- case DIAL:
- if(Tick < DialTimeout) goto exit;
- SendState= DISCON;
- if(check_con()) goto exit;
- /* fall through */
- case DISCON:
- SendState= DIAL;
- DialTimeout= Tick+(10*HZ);
- con_req(0, 0x83, InfoMask, 7, 0, own_eaz+'0',&telno);
- goto exit;
- case IDLE:
- SendState= ACTIVE;
- case ACTIVE:
- {
- word err, i;
- struct buff *sb;
- err= 0; i= 4;
- while(tosend && (err==0) && (SendState==ACTIVE) && --i)
- {
- sb= sendbuf[shead];
- if(sb && (sb->state == WAIT))
- {
- set_prot(sb->sbuf);
- sb->state= SENDING;
- tosend--;
- err=dat_b3_req(Ncci, sb->length, sb->sbuf, shead, 0);
- LastActTime= Tick;
- if(err)
- {
- sb->state= WAIT;
- tosend++;
- goto exit;
- }
- }
- shead++; shead&= 0x3;
- }
- if(i==0) tosend= 0;
- }
- }
- }
- exit: sema= 0;
- }
-
- void checkfree(void)
- {
- int i;
-
- free= 4;
- for(i=0; i<4; i++) if(sendbuf[i]) free--;
- tosend= 4-free;
- }
-
- void
- free_sendbuf(byte ind, word err)
- {
- struct buff *sb;
- sb= sendbuf[ind];
- if(sb)
- {
- if(err)
- {
- if(Tick < sb->timeout)
- {
- sb->state= WAIT;
- checkfree();
- return;
- }
- sb->state= SENDING;
- }
- if(sb->state != SENDING)
- {
- checkfree();
- return;
- }
-
- free++; tosend= 4-free;
- sb->state= EMPTY;
- freebuf(sb);
- sendbuf[ind]= null;
- return;
- }
- /* sb == null */
- checkfree();
- }
-
- void check_buf(void)
- {
- int i;
- struct buff *sb;
-
- for(i=0; i<4; i++)
- {
- sb= sendbuf[i];
- if(sb && (Tick > sb->timeout) && (sb->state == WAIT))
- {
- free++; tosend= 4-free;
- sb->state= EMPTY;
- freebuf(sb);
- sendbuf[i]= null;
- }
- }
- checkfree();
- }
-