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 >
C/C++ Source or Header  |  1993-10-06  |  12KB  |  667 lines

  1. /* PAPI: Packet driver Common ISDN API
  2.     Author: Dietmar Friede
  3. Copyright (c) 1992 D.Friede
  4.  #include "copy"
  5.  #include "copying.doc"
  6. Acknowledgement:
  7. It was slfp.c, a C-language driver for 8250 slip written by
  8. Glenn H McGregor, and William A Simpson, which served as a
  9. skeleton for this file
  10. */
  11.  
  12. #define VERSION    "0.20 05-Oct-1993"
  13.  
  14. #include    "stdio.h"
  15. #include    <stdlib.h>
  16. #include    <conio.h>
  17. #include    <dos.h>
  18. #include    <mem.h>
  19. #include    <string.h>
  20. #include    "types.h"
  21. #include    "gen.h"
  22. #include    "api.h"
  23.  
  24. /* Memory layout */
  25. word    _stklen        =    2048;
  26. word    _heaplen    =    2048;
  27.  
  28. /* Configuration options & defaults */
  29. byte    ConfPackInt    =    0x60;
  30. struct    telno    telno= { 0, 0x81, { 0, 0,} };
  31. struct    telno    ptelno= { 0, 0x81, { 0, 0,} };
  32. char status_line[80]= {' '};
  33. word line= 0;
  34. byte protokoll= 2;
  35. byte own_eaz= 2;
  36. byte headline= 0;
  37. byte PollInt=0;
  38. byte ignore=0;
  39. static unsigned long chrg=0;
  40. dword    InfoMask= 3;
  41.  
  42. dword        IOS_PktIn    =    0;
  43. dword        IOS_PktOut    =    0;
  44. dword        IOS_ByteIn    =    0;
  45. dword        IOS_ByteOut    =    0;
  46. dword        IOS_ErrIn    =    0;
  47. dword        IOS_ErrOut    =    0;
  48. dword        IOS_PktDrop    =    0;
  49. #define    IOS_Table    IOS_PktIn
  50.  
  51. /* Packet Driver Hook */
  52. char    PacketDriverHook[17];
  53. InterruptPtr SavePacketInt;
  54.  
  55. /* Handle Table */
  56. typedef void (far *RecvType)(void);
  57.  
  58. typedef    struct
  59.  {
  60.     byte        Hand_InUse;
  61.     byte        Hand_TypeLen;
  62.     RecvType    Hand_Receiver;
  63.     word        Hand_TypeVal;
  64.  }    HandleType;
  65.  
  66. HandleType        HandleTable;
  67.  
  68. /* Packet Driver values */
  69. #define PD_version    0x0010
  70. #define PDV_basic    1
  71. #define PDV_extended    2
  72. #define    PDT_any        0xffff
  73. char    PDN_papi[]=    "ISDNCAPI";
  74.  
  75. /*  Packet Driver Classes */
  76. #define    PDC_SerialLine    6 
  77.  
  78. /* Function calls */
  79. enum    PD_Functions
  80.  {
  81.     PDF_DriverInfo            =    1,
  82.     PDF_AccessType,
  83.     PDF_ReleaseType,
  84.     PDF_SendPkt,
  85.     PDF_Terminate,
  86.     PDF_GetAddress,
  87.     PDF_ResetInterface,
  88.     PDF_GetStatistics = 24,
  89.  };
  90.  
  91. /*  Error codes */
  92. enum    PD_Errors
  93. {
  94.     PDE_BadHandle            =    1,
  95.     PDE_NoClass,
  96.     PDE_NoType,
  97.     PDE_NoNumber,
  98.     PDE_BadType,
  99.     PDE_NoMulticast,
  100.     PDE_CantTerminate,
  101.     PDE_BadMode,
  102.     PDE_NoSpace,
  103.     PDE_TypeInUse,
  104.     PDE_BadCommand,
  105.     PDE_CantSend,
  106.     PDE_CantSet,
  107.     PDE_BadAddress
  108.  
  109. };
  110.  
  111. int PassDown (byte *buf, word len);
  112. void init_passdown(void);
  113. int api_init (word bsize, word verbose);
  114. void api_stop(void);
  115. word dirps(void);
  116. void restore(word);
  117. int getopt(int argc, char *argv[], char *optionS);
  118. word get_Ncci(void);
  119. extern char *optarg;
  120. extern int optind;
  121.  
  122. extern byte capi_int;
  123. extern word DisTimeout;
  124. extern struct dlpd dlpd;
  125.  
  126. void
  127. PassUp(byte * buf, word len)
  128. {
  129.     RecvType    TempRecv;
  130.     void        *TempPtr;
  131.  
  132.     /* ensure a handle to return message on */
  133.     if ( !HandleTable.Hand_InUse )
  134.     {
  135.         IOS_PktDrop++;
  136.         return;
  137.     }
  138.  
  139.     /* ensure receiver hasn't asked for a specific type */
  140.     if ( HandleTable.Hand_TypeLen != 0 )
  141.     {
  142.         IOS_PktDrop++;
  143.         return;
  144.     }
  145.  
  146.     /* get buffer */
  147.     TempRecv = HandleTable.Hand_Receiver;
  148.     if ( TempRecv == NULL )
  149.     {
  150.         IOS_PktDrop++;
  151.         return;
  152.     }
  153.  
  154.     _AX = 0;
  155.     _CX = len;
  156.     _BX = 1;
  157.     TempRecv();
  158.     TempPtr = (void *) MK_FP ( _ES, _DI );
  159.  
  160.     if ( TempPtr == NULL )
  161.     {
  162.         IOS_PktDrop++;
  163.         return;
  164.     }
  165.  
  166.     /* move data into buffer */
  167.     memcpy ( TempPtr, buf, len );
  168.  
  169.     /* pass up to receiver */
  170.     __emit__ ( 0x1E );            /* push ds */
  171.     _DS = FP_SEG ( TempPtr );
  172.     _SI = FP_OFF ( TempPtr );
  173.     _AX = 1;
  174.     _CX = len;
  175.     _BX = 1;
  176.     TempRecv();
  177.     __emit__ ( 0x1F );            /* pop ds */
  178. }
  179.  
  180. void
  181. DriverInfo(IntrRegsType *IntrRegs)
  182. {
  183.     /* ensure real function */
  184.     if ( IntrRegs->b.al != 0xff )
  185.     {
  186.         IntrRegs->w.fl |= FL_CARRY;
  187.         IntrRegs->b.dh = PDE_BadCommand;
  188.         return;
  189.     }
  190.  
  191.     /* return driver info */
  192.     IntrRegs->w.fl &= ~FL_CARRY;
  193.     IntrRegs->w.bx = PD_version;
  194.     IntrRegs->b.ch = PDC_SerialLine;
  195.     IntrRegs->w.dx = 0xffff;
  196.     IntrRegs->b.cl = 0;        /* number */
  197.     IntrRegs->w.ds = FP_SEG(PDN_papi);
  198.     IntrRegs->w.si = FP_OFF(PDN_papi);
  199.     IntrRegs->b.al = PDV_extended;
  200. }
  201.  
  202. void
  203. AccessType(IntrRegsType *IntrRegs)
  204. {
  205.     /* assume error */
  206.     IntrRegs->w.fl |= FL_CARRY;
  207.  
  208.     /* ensure SerialLine class request */
  209.     if ( IntrRegs->b.al != PDC_SerialLine )
  210.     {
  211.         IntrRegs->b.dh = PDE_NoClass;
  212.         return;
  213.     }
  214.  
  215.     /* ensure proper type request */
  216.     if(IntrRegs->w.bx != PDT_any )
  217.     {
  218.         IntrRegs->b.dh = PDE_NoType;
  219.         return;
  220.     }
  221.  
  222.     /* ensure proper number request */
  223.     if ( ( IntrRegs->b.dl != 0 ) && ( IntrRegs->b.dl != 1 ) )
  224.     {
  225.         IntrRegs->b.dh = PDE_NoNumber;
  226.         return;
  227.     }
  228.  
  229.     /* ensure already not in use */
  230.     if ( HandleTable.Hand_InUse )
  231.     {
  232.         IntrRegs->b.dh = PDE_TypeInUse;
  233.         return;
  234.     }
  235.  
  236.     /* type value length must be <= 8 */
  237.     if ( IntrRegs->w.cx > 8 )
  238.     {
  239.         IntrRegs->b.dh = PDE_BadType;
  240.         return;
  241.     }
  242.  
  243.     /* enter info into handler table entry */
  244.     HandleTable.Hand_InUse = TRUE;
  245.     HandleTable.Hand_Receiver =
  246.         (RecvType) MK_FP ( IntrRegs->w.es, IntrRegs->w.di );
  247.     HandleTable.Hand_TypeLen = IntrRegs->w.cx;
  248.  
  249.     /* all done */
  250.     IntrRegs->w.fl &= ~FL_CARRY;
  251.     IntrRegs->w.ax = 1;
  252. }
  253.  
  254. void
  255. ReleaseType(IntrRegsType *IntrRegs)
  256. {
  257.     word        hand;
  258.  
  259.     hand = IntrRegs->w.bx;
  260.  
  261.     /* ensure good handle */
  262.     if ( hand != 1 )
  263.     {
  264.         IntrRegs->w.fl |= FL_CARRY;
  265.         IntrRegs->b.dh = PDE_BadHandle;
  266.         return;
  267.     }
  268.  
  269.     /* clear table entry */
  270.     HandleTable.Hand_InUse = FALSE;
  271.     HandleTable.Hand_Receiver = (RecvType) NULL;
  272.  
  273.     /* all done */
  274.     IntrRegs->w.fl &= ~FL_CARRY;
  275. }
  276.  
  277. void
  278. SendPkt(IntrRegsType *IntrRegs)
  279. {
  280.     /* set up */
  281.     IntrRegs->w.fl |= FL_CARRY;
  282.     IntrRegs->b.dh = PDE_CantSend;
  283.  
  284.     if(PassDown((byte *) MK_FP ( IntrRegs->w.ds, IntrRegs->w.si ), IntrRegs->w.cx))
  285.     {
  286.         IOS_ErrOut++;
  287.         return;
  288.     }
  289.  
  290.     /* record stats */
  291.     IOS_PktOut++;
  292.     IOS_ByteOut += IntrRegs->w.cx;
  293.  
  294.     /* all done */
  295.     IntrRegs->w.fl &= ~FL_CARRY;
  296. }
  297.  
  298. void
  299. Terminate(IntrRegsType *IntrRegs)
  300. {
  301.     union    REGS    regs;
  302.     struct    SREGS    sregs;
  303.     int x;
  304.  
  305.     /* restore hardware and interrupts */
  306.     x= dirps();
  307.     api_stop();
  308.     setvect ( ConfPackInt, SavePacketInt );
  309.     restore(x);
  310.  
  311.     /* assume failure */
  312.     IntrRegs->w.fl |= FL_CARRY;
  313.     IntrRegs->b.dh = PDE_CantTerminate;
  314.  
  315.     /* return program block */
  316.     regs.h.ah = 0x49;
  317.     sregs.es = _psp;
  318.     intdosx ( ®s, ®s, &sregs );
  319.     if ( regs.x.cflag != 0 )
  320.         return;
  321.  
  322.     /* return environment block */
  323.     regs.h.ah = 0x49;
  324.     sregs.es = ( (PSP_Ptr) MK_FP ( _psp, 0 ) ) -> PSP_Environment;
  325.     intdosx ( ®s, ®s, &sregs );
  326.     if ( regs.x.cflag != 0 )
  327.         return;
  328.  
  329.     /* all OK */
  330.     IntrRegs->w.fl &= ~FL_CARRY;
  331. }
  332.  
  333. void interrupt
  334. PacketDriver(IntrRegsType IntrRegs)
  335. {
  336.     enable();
  337.  
  338.     switch ( IntrRegs.b.ah )
  339.     {
  340.     case PDF_DriverInfo:
  341.         DriverInfo ( &IntrRegs );
  342.         break;
  343.     case PDF_AccessType:
  344.         AccessType ( &IntrRegs );
  345.         break;
  346.     case PDF_ReleaseType:
  347.         ReleaseType ( &IntrRegs );
  348.         break;
  349.     case PDF_SendPkt:
  350.         SendPkt ( &IntrRegs );
  351.         break;
  352.     case PDF_Terminate:
  353.         Terminate ( &IntrRegs );
  354.         break;
  355.     case PDF_GetAddress:
  356.         IntrRegs.w.fl &= ~FL_CARRY;
  357.         IntrRegs.w.cx = 0;
  358.         break;
  359.     case PDF_GetStatistics:
  360.         IntrRegs.w.fl &= ~FL_CARRY;
  361.         IntrRegs.w.ds = FP_SEG ( &IOS_Table );
  362.         IntrRegs.w.si = FP_OFF ( &IOS_Table );
  363.         break;
  364.     default:
  365.         IntrRegs.w.fl |= FL_CARRY;
  366.         IntrRegs.b.dh = PDE_BadCommand;
  367.     }
  368. }
  369.  
  370. static void
  371. usage(void)
  372. {
  373.     printf ( "Usage: papi [-v] [-V] [-x] [-u] [-t] [-T] [-o eaz] -n telno\n"
  374.         "    [ -i ] [ -P ] [ -N telno ]\n"
  375.         "    [-p PacketIntNo] [-c CAPIIntNo] [-w Timeout] [-s BufSize]\n");
  376. }
  377.  
  378. byte
  379. GetDig ( char ch )
  380. {
  381.     if ( ( ch >= '0' ) && ( ch <= '9' ) ) return ch - '0';
  382.     else if ( ( ch >= 'A' ) && ( ch <= 'F' ) ) return ch - 'A' + 10;
  383.     else if ( ( ch >= 'a' ) && ( ch <= 'f' ) ) return ch - 'a' + 10;
  384.     else if ( ( ch == 'x' ) || ( ch == 'X' ) ) return 'x';
  385.     else if ( ch == '#' ) return '#';
  386.     else if ( ch == 0 ) return '0';
  387.     else return '?';
  388. }
  389.  
  390. dword
  391. GetNum(void)
  392. {
  393.     byte        state;
  394.     dword        base;
  395.     dword        num;
  396.     char        ch;
  397.     byte        digit;
  398.  
  399.     num = 0;
  400.     state = 0;
  401.  
  402.     for (;;)
  403.     {
  404.         ch = *optarg++;
  405.         digit = GetDig ( ch );
  406.         switch ( state )
  407.         {
  408.         case 0:
  409.             if ( digit == 0 )
  410.             {
  411.                 base = 8;
  412.                 state = 1;
  413.             }
  414.             else if ( digit == '#' )
  415.             {
  416.                 base = 16;
  417.                 state = 3;
  418.             }
  419.             else if ( digit <= 9 )
  420.             {
  421.                 base = 10;
  422.                 num = digit;
  423.                 state = 2;
  424.             }
  425.             else return ErrInt;
  426.             break;
  427.         case 1:
  428.             if ( digit == 'x' )
  429.             {
  430.                 if ( num == 0 )
  431.                 {
  432.                     base = 16;
  433.                     state = 3;
  434.                 }
  435.                 else return ErrInt;
  436.             }
  437.             else if ( digit <= 9 ) num = num * base + digit;
  438.             else if ( digit == '0' ) return num;
  439.             else return ErrInt;
  440.             break;
  441.         case 2:
  442.             if ( digit == '#' )
  443.             {
  444.                 base = num;
  445.                 num = 0;
  446.                 if ( ( base < 2 ) || ( base > 16 ) )
  447.                     return ErrInt;
  448.                 state = 3;
  449.             }
  450.             else if ( digit <= 9 )     num = num * base + digit;
  451.             else if ( digit == '0' ) return num;
  452.             else return ErrInt;
  453.             break;
  454.         case 3:
  455.             if ( digit < base ) num = num * base + digit;
  456.             else if ( digit == '0' ) return num;
  457.             else return ErrInt;
  458.             break;
  459.         }
  460.     }
  461. }
  462.  
  463. void
  464. copytelno(struct telno *t, byte *p)
  465. {
  466.     int i;
  467.  
  468.     for(i=0;*p && (i<15); i++,p++) t->no[i]= *p;
  469.     if(t->no[i-1] == 'S') t->no[i-1]='s';
  470.     if(t->no[i-1] == 's') InfoMask|= 0x40000000;
  471.  
  472.     t->length= i+1;
  473.     t->no[i]= 0;
  474. }
  475.  
  476. void
  477. main ( int argc, char **argv )
  478. {
  479.     void    *HookPtr;
  480.     dword    PSize;
  481.     int    opt;
  482.     InterruptPtr OldPackInt;
  483.     char    PDSig[8];
  484.     word    bsize, verbose, notelno, nopassno;
  485.  
  486.     bsize= 2048;
  487.     verbose= 0;
  488.     notelno= 1;
  489.     nopassno= 1;
  490.  
  491.     init_printf();
  492.     while((opt = getopt(argc, argv, "ivxuPtTc:o:n:N:p:w:s:S:V:")) != -1)
  493.     {
  494.         switch ( opt )
  495.         {
  496.         case 'i':
  497.             ignore++;
  498.             break;
  499.         case 'v':
  500.             verbose++;
  501.             break;
  502.         case 'T':
  503.         case 'x': protokoll= 1;
  504.             break;
  505.         case 'u': protokoll= 2;
  506.             break;
  507.         case 't': protokoll= 3;
  508.             break;
  509.         case 'c':
  510.             capi_int = GetNum();
  511.             break;
  512.         case 'p':
  513.             ConfPackInt = GetNum();
  514.             break;
  515.         case 'P':
  516.             PollInt++;
  517.             break;
  518.         case 'o':
  519.             own_eaz = GetNum();
  520.             if((own_eaz < 0) || (own_eaz > 9))
  521.             {
  522.                 printf("bad eaz\n");
  523.                 usage();
  524.             }
  525.             break;
  526.         case 'n':
  527.             copytelno(&telno, (byte *) optarg);
  528.             notelno= 0;
  529.             break;
  530.         case 'N':
  531.             copytelno(&ptelno, (byte *) optarg);
  532.             nopassno= 0;
  533.             break;
  534.         case 'w':
  535.             DisTimeout = (word) GetNum() * HZ;
  536.             break;
  537.         case 's':
  538.             bsize = (word) GetNum();
  539.             break;
  540.         case 'S':
  541.             dlpd.data_length= (word) GetNum();
  542.             break;
  543.         case 'V':
  544.             headline++;
  545.             line= (word) (GetNum() * 160);
  546.             break;
  547.         case -1: break;
  548.         default:
  549.             usage();
  550.         }
  551.     }
  552.  
  553.     if(notelno)
  554.     {
  555.         printf("No host telefon number\n");
  556.         usage();
  557.     }
  558.     if(nopassno) ptelno= telno;
  559.     
  560.     if(verbose) printf("PAPI: version " VERSION "\n(c) 1992 D.Friede\n");
  561.  
  562.     /* check for packet driver already loaded */
  563.     OldPackInt = getvect ( ConfPackInt );
  564.     movedata(FP_SEG(OldPackInt), FP_OFF(OldPackInt)+3, FP_SEG(PDSig), FP_OFF(PDSig), 8);
  565.     if ( strncmp ( PDSig, "PKT DRVR", 8 ) == 0 )
  566.     {
  567.         printf("Packet driver already loaded at 0x%X\n", ConfPackInt );
  568.         exit(1);
  569.     }
  570.  
  571.     /* clear Handle table */
  572.     HandleTable.Hand_InUse = FALSE;
  573.     HandleTable.Hand_Receiver = (RecvType) NULL;
  574.  
  575.     /* build driver hook */
  576.     memcpy ( PacketDriverHook, "\xEB\x0A\x90PKT DRVR\0\xEA", 13 );
  577.     HookPtr = (void *)PacketDriver;
  578.     memcpy ( &PacketDriverHook[13], &HookPtr, 4 );
  579.  
  580.     /* set up packet driver vector */
  581.     SavePacketInt = getvect ( ConfPackInt );
  582.     setvect ( ConfPackInt, (InterruptPtr) PacketDriverHook );
  583.  
  584.     init_passdown();
  585.     /* initialize isdn capi */
  586.     if(api_init (bsize, verbose))
  587.     {
  588.         int x;
  589.         x= dirps();
  590.         setvect ( ConfPackInt, SavePacketInt );
  591.         restore(x);
  592.         printf("Packet driver not installed\n");
  593.         exit(1);
  594.     }
  595.  
  596.     /* terminate, stay resident */
  597.     PSize= ((byte huge *)MK_FP(_SS,_SP+15)-(byte huge *)MK_FP(_CS,0)) / 16;
  598.     if(verbose) printf("Packet driver loaded at 0x%x size %ldK\n",ConfPackInt,(PSize*16)/1024);
  599.     keep(0, (unsigned)PSize);
  600. }
  601.  
  602. int
  603. accept_con_ind(byte serv, byte serv_add, byte eaz, struct telno *num)
  604. {
  605.     char *p;
  606.     unsigned l;
  607.     if((serv != 7) || ((eaz-'0') != own_eaz))
  608.     {
  609.         printf("PAPI: bad service %x or bad eaz %c\n",serv,eaz);
  610.         return 0;
  611.     }
  612.     if(serv_add != 0) printf("PAPI: warning: strange additional service byte %x\n",serv_add);
  613.     l= num->length; l--;
  614.     if(l>16) l= 16;
  615.     num->no[l]= 0;
  616.  
  617.     if(ignore == 0)
  618.     if(((p= strstr((char *) num->no,(char *) ptelno.no)) == null) ||
  619.         strcmp((char *) ptelno.no,p))
  620.     {
  621.         printf("PAPI: warning Intruder ? %s\n",num->no);
  622.         return 0;
  623.     }
  624.     if(get_Ncci()>DIAL) return 0;
  625.     for(l=0; l < (num->length-1); l++) status_line[40+l]= num->no[l];
  626.     return 1;
  627. }
  628.  
  629. void
  630. pass_up_info(byte *c, byte s)
  631. {
  632.     int i,j,ln;
  633.     byte no;
  634.     char *p;
  635.  
  636.     c+= 2;
  637.     no= *c;
  638.     c+= 2;
  639.     ln= *c;
  640.     c++;
  641.     c[ln]= 0;
  642.     p= status_line;
  643.  
  644.     switch(no)
  645.     {
  646.     case 2:
  647.         p+= 20;
  648.         if(s)
  649.         {
  650.             unsigned long n;
  651.             n=++chrg;
  652.             for(i=5; i>= 0; i--,n/=10) p[i]= '0'+(n%10);
  653.             if(n) chrg= 0;
  654.         }
  655.         p+=10;
  656.         c++; ln--;
  657.         if(ln>4) return;
  658.         for(i=0;i<4;i++) p[i]='0';
  659.         if(s==0) return;
  660.         for(i=4-ln,j=0;i<4 ;i++,j++) p[i]=c[j];
  661.         return;
  662.     case 3:
  663.         for(i=0;i<20;i++)p[i]=c[i];
  664.         return;
  665.     }
  666. }
  667.