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

  1. /* Common ISDN API C-Library Functions: pass down handling for papi.c
  2.     Author: Dietmar Friede
  3. Copyright (c) 1992 D.Friede
  4.  #include "copy"
  5.  #include "copying.doc"
  6. */
  7. #include "stdio.h"
  8. #include <dos.h>
  9. #include <mem.h>
  10. #include "types.h"
  11. #include "api.h"
  12.  
  13. typedef enum { EMPTY, GOT, WAIT, SENDING} bstate;
  14.  
  15. struct buff
  16.  {
  17.     bstate state;
  18.     word length;
  19.     dword timeout;
  20.     byte sbuf[2052];
  21.  };
  22. static struct buff *sendbuf[4];
  23. static word free, head, shead, tosend;
  24. extern byte own_eaz;
  25.  
  26. extern io_state SendState;
  27. extern struct telno telno;
  28. extern word Ncci;
  29. extern dword Tick, LastActTime;
  30. extern dword InfoMask;
  31. static dword DialTimeout= 0;
  32.  
  33. int check_con(void);
  34. void init_buf(void);
  35. struct buff *getbuf(void);
  36. void freebuf(struct buff *p);
  37. byte get_prot_size(void);
  38. void set_prot(byte * p);
  39. word get_Ncci(void);
  40. void startsend(void);
  41. void check_buf(void);
  42. 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);
  43. int dat_b3_req(word ncci, word dat_length, byte *data, byte number, word flags);
  44. word dirps(void);
  45. void restore(word w);
  46.  
  47. void
  48. init_passdown(void)
  49. {
  50.     int i;
  51.     for(i=0 ; i<4; i++) sendbuf[i]= null;
  52.     init_buf();
  53.     free= 4;
  54.     shead= head= tosend= 0;
  55. }
  56.  
  57. int
  58. PassDown(byte *buf, word len)
  59. {
  60.     register word l;
  61.     byte ps;
  62.     byte *p;
  63.     struct buff *sb;
  64.     word x;
  65.  
  66.     if((len == 0) || (buf ==null)) return 1;
  67.  
  68.     x= dirps();
  69.     if((free == 0) || ((sb= getbuf()) == null))
  70.     {
  71.         check_buf();
  72.         startsend();
  73.         restore(x);
  74.         return 1;
  75.     }
  76.     free --; tosend++;
  77.     l= 4;
  78.     while(sendbuf[head] && --l )
  79.     {
  80.         head++; head&= 0x3;
  81.     }
  82.     if(l == 0)
  83.     {
  84.         freebuf(sb);
  85.         restore(x);
  86.         return 1;
  87.     }
  88.  
  89.     sendbuf[head++]= sb;
  90.     head&= 0x3;
  91.     sb->state= GOT;
  92.     p= sb->sbuf;
  93.  
  94.     ps= get_prot_size();
  95.     memcpy(p+ps,buf,len);
  96.     sb->length= len+ps;
  97.     sb->state= WAIT;
  98.     sb->timeout= Tick+15*HZ;
  99.     startsend();
  100.     restore(x);
  101.     return 0;
  102. }
  103.  
  104. void
  105. startsend(void)
  106. {
  107.     static int sema= 0;
  108.     if(sema++) return;
  109.  
  110.     if(tosend)
  111.     { 
  112.         get_Ncci();
  113.         switch(SendState)
  114.         {
  115.         case DIAL:
  116.             if(Tick < DialTimeout) goto exit;
  117.             SendState= DISCON;
  118.             if(check_con()) goto exit;
  119.             /* fall through */
  120.         case DISCON:
  121.             SendState= DIAL;
  122.             DialTimeout= Tick+(10*HZ);
  123.             con_req(0, 0x83, InfoMask, 7, 0, own_eaz+'0',&telno);
  124.             goto exit;
  125.         case IDLE:
  126.             SendState= ACTIVE;
  127.         case ACTIVE:
  128.             {
  129.               word err, i;
  130.               struct buff *sb;
  131.               err= 0; i= 4;
  132.               while(tosend && (err==0) && (SendState==ACTIVE) && --i)
  133.                 {
  134.                 sb= sendbuf[shead];
  135.                 if(sb && (sb->state == WAIT))
  136.                 {
  137.                   set_prot(sb->sbuf);
  138.                   sb->state= SENDING;
  139.                   tosend--;
  140.                   err=dat_b3_req(Ncci, sb->length, sb->sbuf, shead, 0);
  141.                   LastActTime= Tick;
  142.                   if(err)
  143.                   {
  144.                     sb->state= WAIT;
  145.                     tosend++;
  146.                     goto exit;
  147.                   }
  148.                 } 
  149.                  shead++; shead&= 0x3;
  150.                 }
  151.                 if(i==0) tosend= 0;
  152.             }
  153.         }
  154.     }
  155. exit:    sema= 0;
  156. }
  157.  
  158. void checkfree(void)
  159. {
  160.     int i;
  161.  
  162.     free= 4;
  163.     for(i=0; i<4; i++) if(sendbuf[i]) free--;
  164.     tosend= 4-free;
  165. }    
  166.  
  167. void
  168. free_sendbuf(byte ind, word err)
  169. {
  170.     struct buff *sb;
  171.     sb= sendbuf[ind];
  172.     if(sb)
  173.     {
  174.         if(err)
  175.         {
  176.             if(Tick < sb->timeout)
  177.             {
  178.                 sb->state= WAIT;
  179.                 checkfree();
  180.                 return;
  181.             }
  182.             sb->state= SENDING;
  183.         }
  184.         if(sb->state != SENDING)
  185.         {
  186.             checkfree();
  187.             return;
  188.         }
  189.  
  190.         free++; tosend= 4-free;
  191.         sb->state= EMPTY;
  192.         freebuf(sb);
  193.         sendbuf[ind]= null;
  194.         return;
  195.     }
  196.     /* sb == null */
  197.     checkfree();
  198. }
  199.  
  200. void check_buf(void)
  201. {
  202.     int i;
  203.     struct buff *sb;
  204.  
  205.     for(i=0; i<4; i++)
  206.     {
  207.         sb= sendbuf[i];
  208.         if(sb && (Tick > sb->timeout) && (sb->state == WAIT))
  209.         {
  210.             free++; tosend= 4-free;
  211.             sb->state= EMPTY;
  212.             freebuf(sb);
  213.             sendbuf[i]= null;
  214.         }
  215.     }
  216.     checkfree();
  217. }
  218.