home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
ctcoll95.zip
/
BASTELST
/
PAPI020.ZIP
/
PAPI.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-10-06
|
12KB
|
667 lines
/* PAPI: Packet driver Common ISDN API
Author: Dietmar Friede
Copyright (c) 1992 D.Friede
#include "copy"
#include "copying.doc"
Acknowledgement:
It was slfp.c, a C-language driver for 8250 slip written by
Glenn H McGregor, and William A Simpson, which served as a
skeleton for this file
*/
#define VERSION "0.20 05-Oct-1993"
#include "stdio.h"
#include <stdlib.h>
#include <conio.h>
#include <dos.h>
#include <mem.h>
#include <string.h>
#include "types.h"
#include "gen.h"
#include "api.h"
/* Memory layout */
word _stklen = 2048;
word _heaplen = 2048;
/* Configuration options & defaults */
byte ConfPackInt = 0x60;
struct telno telno= { 0, 0x81, { 0, 0,} };
struct telno ptelno= { 0, 0x81, { 0, 0,} };
char status_line[80]= {' '};
word line= 0;
byte protokoll= 2;
byte own_eaz= 2;
byte headline= 0;
byte PollInt=0;
byte ignore=0;
static unsigned long chrg=0;
dword InfoMask= 3;
dword IOS_PktIn = 0;
dword IOS_PktOut = 0;
dword IOS_ByteIn = 0;
dword IOS_ByteOut = 0;
dword IOS_ErrIn = 0;
dword IOS_ErrOut = 0;
dword IOS_PktDrop = 0;
#define IOS_Table IOS_PktIn
/* Packet Driver Hook */
char PacketDriverHook[17];
InterruptPtr SavePacketInt;
/* Handle Table */
typedef void (far *RecvType)(void);
typedef struct
{
byte Hand_InUse;
byte Hand_TypeLen;
RecvType Hand_Receiver;
word Hand_TypeVal;
} HandleType;
HandleType HandleTable;
/* Packet Driver values */
#define PD_version 0x0010
#define PDV_basic 1
#define PDV_extended 2
#define PDT_any 0xffff
char PDN_papi[]= "ISDNCAPI";
/* Packet Driver Classes */
#define PDC_SerialLine 6
/* Function calls */
enum PD_Functions
{
PDF_DriverInfo = 1,
PDF_AccessType,
PDF_ReleaseType,
PDF_SendPkt,
PDF_Terminate,
PDF_GetAddress,
PDF_ResetInterface,
PDF_GetStatistics = 24,
};
/* Error codes */
enum PD_Errors
{
PDE_BadHandle = 1,
PDE_NoClass,
PDE_NoType,
PDE_NoNumber,
PDE_BadType,
PDE_NoMulticast,
PDE_CantTerminate,
PDE_BadMode,
PDE_NoSpace,
PDE_TypeInUse,
PDE_BadCommand,
PDE_CantSend,
PDE_CantSet,
PDE_BadAddress
};
int PassDown (byte *buf, word len);
void init_passdown(void);
int api_init (word bsize, word verbose);
void api_stop(void);
word dirps(void);
void restore(word);
int getopt(int argc, char *argv[], char *optionS);
word get_Ncci(void);
extern char *optarg;
extern int optind;
extern byte capi_int;
extern word DisTimeout;
extern struct dlpd dlpd;
void
PassUp(byte * buf, word len)
{
RecvType TempRecv;
void *TempPtr;
/* ensure a handle to return message on */
if ( !HandleTable.Hand_InUse )
{
IOS_PktDrop++;
return;
}
/* ensure receiver hasn't asked for a specific type */
if ( HandleTable.Hand_TypeLen != 0 )
{
IOS_PktDrop++;
return;
}
/* get buffer */
TempRecv = HandleTable.Hand_Receiver;
if ( TempRecv == NULL )
{
IOS_PktDrop++;
return;
}
_AX = 0;
_CX = len;
_BX = 1;
TempRecv();
TempPtr = (void *) MK_FP ( _ES, _DI );
if ( TempPtr == NULL )
{
IOS_PktDrop++;
return;
}
/* move data into buffer */
memcpy ( TempPtr, buf, len );
/* pass up to receiver */
__emit__ ( 0x1E ); /* push ds */
_DS = FP_SEG ( TempPtr );
_SI = FP_OFF ( TempPtr );
_AX = 1;
_CX = len;
_BX = 1;
TempRecv();
__emit__ ( 0x1F ); /* pop ds */
}
void
DriverInfo(IntrRegsType *IntrRegs)
{
/* ensure real function */
if ( IntrRegs->b.al != 0xff )
{
IntrRegs->w.fl |= FL_CARRY;
IntrRegs->b.dh = PDE_BadCommand;
return;
}
/* return driver info */
IntrRegs->w.fl &= ~FL_CARRY;
IntrRegs->w.bx = PD_version;
IntrRegs->b.ch = PDC_SerialLine;
IntrRegs->w.dx = 0xffff;
IntrRegs->b.cl = 0; /* number */
IntrRegs->w.ds = FP_SEG(PDN_papi);
IntrRegs->w.si = FP_OFF(PDN_papi);
IntrRegs->b.al = PDV_extended;
}
void
AccessType(IntrRegsType *IntrRegs)
{
/* assume error */
IntrRegs->w.fl |= FL_CARRY;
/* ensure SerialLine class request */
if ( IntrRegs->b.al != PDC_SerialLine )
{
IntrRegs->b.dh = PDE_NoClass;
return;
}
/* ensure proper type request */
if(IntrRegs->w.bx != PDT_any )
{
IntrRegs->b.dh = PDE_NoType;
return;
}
/* ensure proper number request */
if ( ( IntrRegs->b.dl != 0 ) && ( IntrRegs->b.dl != 1 ) )
{
IntrRegs->b.dh = PDE_NoNumber;
return;
}
/* ensure already not in use */
if ( HandleTable.Hand_InUse )
{
IntrRegs->b.dh = PDE_TypeInUse;
return;
}
/* type value length must be <= 8 */
if ( IntrRegs->w.cx > 8 )
{
IntrRegs->b.dh = PDE_BadType;
return;
}
/* enter info into handler table entry */
HandleTable.Hand_InUse = TRUE;
HandleTable.Hand_Receiver =
(RecvType) MK_FP ( IntrRegs->w.es, IntrRegs->w.di );
HandleTable.Hand_TypeLen = IntrRegs->w.cx;
/* all done */
IntrRegs->w.fl &= ~FL_CARRY;
IntrRegs->w.ax = 1;
}
void
ReleaseType(IntrRegsType *IntrRegs)
{
word hand;
hand = IntrRegs->w.bx;
/* ensure good handle */
if ( hand != 1 )
{
IntrRegs->w.fl |= FL_CARRY;
IntrRegs->b.dh = PDE_BadHandle;
return;
}
/* clear table entry */
HandleTable.Hand_InUse = FALSE;
HandleTable.Hand_Receiver = (RecvType) NULL;
/* all done */
IntrRegs->w.fl &= ~FL_CARRY;
}
void
SendPkt(IntrRegsType *IntrRegs)
{
/* set up */
IntrRegs->w.fl |= FL_CARRY;
IntrRegs->b.dh = PDE_CantSend;
if(PassDown((byte *) MK_FP ( IntrRegs->w.ds, IntrRegs->w.si ), IntrRegs->w.cx))
{
IOS_ErrOut++;
return;
}
/* record stats */
IOS_PktOut++;
IOS_ByteOut += IntrRegs->w.cx;
/* all done */
IntrRegs->w.fl &= ~FL_CARRY;
}
void
Terminate(IntrRegsType *IntrRegs)
{
union REGS regs;
struct SREGS sregs;
int x;
/* restore hardware and interrupts */
x= dirps();
api_stop();
setvect ( ConfPackInt, SavePacketInt );
restore(x);
/* assume failure */
IntrRegs->w.fl |= FL_CARRY;
IntrRegs->b.dh = PDE_CantTerminate;
/* return program block */
regs.h.ah = 0x49;
sregs.es = _psp;
intdosx ( ®s, ®s, &sregs );
if ( regs.x.cflag != 0 )
return;
/* return environment block */
regs.h.ah = 0x49;
sregs.es = ( (PSP_Ptr) MK_FP ( _psp, 0 ) ) -> PSP_Environment;
intdosx ( ®s, ®s, &sregs );
if ( regs.x.cflag != 0 )
return;
/* all OK */
IntrRegs->w.fl &= ~FL_CARRY;
}
void interrupt
PacketDriver(IntrRegsType IntrRegs)
{
enable();
switch ( IntrRegs.b.ah )
{
case PDF_DriverInfo:
DriverInfo ( &IntrRegs );
break;
case PDF_AccessType:
AccessType ( &IntrRegs );
break;
case PDF_ReleaseType:
ReleaseType ( &IntrRegs );
break;
case PDF_SendPkt:
SendPkt ( &IntrRegs );
break;
case PDF_Terminate:
Terminate ( &IntrRegs );
break;
case PDF_GetAddress:
IntrRegs.w.fl &= ~FL_CARRY;
IntrRegs.w.cx = 0;
break;
case PDF_GetStatistics:
IntrRegs.w.fl &= ~FL_CARRY;
IntrRegs.w.ds = FP_SEG ( &IOS_Table );
IntrRegs.w.si = FP_OFF ( &IOS_Table );
break;
default:
IntrRegs.w.fl |= FL_CARRY;
IntrRegs.b.dh = PDE_BadCommand;
}
}
static void
usage(void)
{
printf ( "Usage: papi [-v] [-V] [-x] [-u] [-t] [-T] [-o eaz] -n telno\n"
" [ -i ] [ -P ] [ -N telno ]\n"
" [-p PacketIntNo] [-c CAPIIntNo] [-w Timeout] [-s BufSize]\n");
}
byte
GetDig ( char ch )
{
if ( ( ch >= '0' ) && ( ch <= '9' ) ) return ch - '0';
else if ( ( ch >= 'A' ) && ( ch <= 'F' ) ) return ch - 'A' + 10;
else if ( ( ch >= 'a' ) && ( ch <= 'f' ) ) return ch - 'a' + 10;
else if ( ( ch == 'x' ) || ( ch == 'X' ) ) return 'x';
else if ( ch == '#' ) return '#';
else if ( ch == 0 ) return '0';
else return '?';
}
dword
GetNum(void)
{
byte state;
dword base;
dword num;
char ch;
byte digit;
num = 0;
state = 0;
for (;;)
{
ch = *optarg++;
digit = GetDig ( ch );
switch ( state )
{
case 0:
if ( digit == 0 )
{
base = 8;
state = 1;
}
else if ( digit == '#' )
{
base = 16;
state = 3;
}
else if ( digit <= 9 )
{
base = 10;
num = digit;
state = 2;
}
else return ErrInt;
break;
case 1:
if ( digit == 'x' )
{
if ( num == 0 )
{
base = 16;
state = 3;
}
else return ErrInt;
}
else if ( digit <= 9 ) num = num * base + digit;
else if ( digit == '0' ) return num;
else return ErrInt;
break;
case 2:
if ( digit == '#' )
{
base = num;
num = 0;
if ( ( base < 2 ) || ( base > 16 ) )
return ErrInt;
state = 3;
}
else if ( digit <= 9 ) num = num * base + digit;
else if ( digit == '0' ) return num;
else return ErrInt;
break;
case 3:
if ( digit < base ) num = num * base + digit;
else if ( digit == '0' ) return num;
else return ErrInt;
break;
}
}
}
void
copytelno(struct telno *t, byte *p)
{
int i;
for(i=0;*p && (i<15); i++,p++) t->no[i]= *p;
if(t->no[i-1] == 'S') t->no[i-1]='s';
if(t->no[i-1] == 's') InfoMask|= 0x40000000;
t->length= i+1;
t->no[i]= 0;
}
void
main ( int argc, char **argv )
{
void *HookPtr;
dword PSize;
int opt;
InterruptPtr OldPackInt;
char PDSig[8];
word bsize, verbose, notelno, nopassno;
bsize= 2048;
verbose= 0;
notelno= 1;
nopassno= 1;
init_printf();
while((opt = getopt(argc, argv, "ivxuPtTc:o:n:N:p:w:s:S:V:")) != -1)
{
switch ( opt )
{
case 'i':
ignore++;
break;
case 'v':
verbose++;
break;
case 'T':
case 'x': protokoll= 1;
break;
case 'u': protokoll= 2;
break;
case 't': protokoll= 3;
break;
case 'c':
capi_int = GetNum();
break;
case 'p':
ConfPackInt = GetNum();
break;
case 'P':
PollInt++;
break;
case 'o':
own_eaz = GetNum();
if((own_eaz < 0) || (own_eaz > 9))
{
printf("bad eaz\n");
usage();
}
break;
case 'n':
copytelno(&telno, (byte *) optarg);
notelno= 0;
break;
case 'N':
copytelno(&ptelno, (byte *) optarg);
nopassno= 0;
break;
case 'w':
DisTimeout = (word) GetNum() * HZ;
break;
case 's':
bsize = (word) GetNum();
break;
case 'S':
dlpd.data_length= (word) GetNum();
break;
case 'V':
headline++;
line= (word) (GetNum() * 160);
break;
case -1: break;
default:
usage();
}
}
if(notelno)
{
printf("No host telefon number\n");
usage();
}
if(nopassno) ptelno= telno;
if(verbose) printf("PAPI: version " VERSION "\n(c) 1992 D.Friede\n");
/* check for packet driver already loaded */
OldPackInt = getvect ( ConfPackInt );
movedata(FP_SEG(OldPackInt), FP_OFF(OldPackInt)+3, FP_SEG(PDSig), FP_OFF(PDSig), 8);
if ( strncmp ( PDSig, "PKT DRVR", 8 ) == 0 )
{
printf("Packet driver already loaded at 0x%X\n", ConfPackInt );
exit(1);
}
/* clear Handle table */
HandleTable.Hand_InUse = FALSE;
HandleTable.Hand_Receiver = (RecvType) NULL;
/* build driver hook */
memcpy ( PacketDriverHook, "\xEB\x0A\x90PKT DRVR\0\xEA", 13 );
HookPtr = (void *)PacketDriver;
memcpy ( &PacketDriverHook[13], &HookPtr, 4 );
/* set up packet driver vector */
SavePacketInt = getvect ( ConfPackInt );
setvect ( ConfPackInt, (InterruptPtr) PacketDriverHook );
init_passdown();
/* initialize isdn capi */
if(api_init (bsize, verbose))
{
int x;
x= dirps();
setvect ( ConfPackInt, SavePacketInt );
restore(x);
printf("Packet driver not installed\n");
exit(1);
}
/* terminate, stay resident */
PSize= ((byte huge *)MK_FP(_SS,_SP+15)-(byte huge *)MK_FP(_CS,0)) / 16;
if(verbose) printf("Packet driver loaded at 0x%x size %ldK\n",ConfPackInt,(PSize*16)/1024);
keep(0, (unsigned)PSize);
}
int
accept_con_ind(byte serv, byte serv_add, byte eaz, struct telno *num)
{
char *p;
unsigned l;
if((serv != 7) || ((eaz-'0') != own_eaz))
{
printf("PAPI: bad service %x or bad eaz %c\n",serv,eaz);
return 0;
}
if(serv_add != 0) printf("PAPI: warning: strange additional service byte %x\n",serv_add);
l= num->length; l--;
if(l>16) l= 16;
num->no[l]= 0;
if(ignore == 0)
if(((p= strstr((char *) num->no,(char *) ptelno.no)) == null) ||
strcmp((char *) ptelno.no,p))
{
printf("PAPI: warning Intruder ? %s\n",num->no);
return 0;
}
if(get_Ncci()>DIAL) return 0;
for(l=0; l < (num->length-1); l++) status_line[40+l]= num->no[l];
return 1;
}
void
pass_up_info(byte *c, byte s)
{
int i,j,ln;
byte no;
char *p;
c+= 2;
no= *c;
c+= 2;
ln= *c;
c++;
c[ln]= 0;
p= status_line;
switch(no)
{
case 2:
p+= 20;
if(s)
{
unsigned long n;
n=++chrg;
for(i=5; i>= 0; i--,n/=10) p[i]= '0'+(n%10);
if(n) chrg= 0;
}
p+=10;
c++; ln--;
if(ln>4) return;
for(i=0;i<4;i++) p[i]='0';
if(s==0) return;
for(i=4-ln,j=0;i<4 ;i++,j++) p[i]=c[j];
return;
case 3:
for(i=0;i<20;i++)p[i]=c[i];
return;
}
}