home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
ctcoll95.zip
/
BASTELST
/
PAPI020.ZIP
/
SEND.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-10-06
|
4KB
|
218 lines
/* 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();
}