home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ctcoll95.zip / BASTELST / PAPI020.ZIP / APIINTR.C < prev    next >
C/C++ Source or Header  |  1993-10-06  |  10KB  |  440 lines

  1. /* Common ISDN API C-Library Functions: interupt handler
  2.     Author: Dietmar Friede
  3. Copyright (c) 1992 D.Friede
  4.  #include "copy"
  5.  #include "copying.doc"
  6. */
  7. #include "stdio.h"
  8. #include "types.h"
  9. #include "api.h"
  10.  
  11. struct dlpd dlpd= {7,2048,0,0,0,0,0};
  12. static byte nullstruct[1] = {0};
  13. static io_state send_state= DISCON;
  14. static io_state rcv_state= DISCON;
  15. static long send_plci= -1, rcv_plci= -1;
  16. static word send_ncci= 0xffff, rcv_ncci= 0xfffe;
  17. static byte ListenErr= 0xff;
  18. static byte CheckListen= 1;
  19. static word rcv_ind_msg_nr;
  20. static word api_int_mark= 0;
  21.  
  22. word SendState= 0;
  23. word SendDir= 0;
  24. word Ncci= 0xfffd;
  25. byte is_api_int= 0;
  26. dword send_err= 0, Tick= 0, LastActTime= 0;
  27.  
  28. extern byte protokoll;
  29. extern byte PollInt;
  30. extern byte headline;
  31. extern char status_line[80];
  32.  
  33. byte get_prot_size(void);
  34. int accept_con_ind(byte serv, byte serv_add, byte eaz, struct telno *num);
  35. int api_get_message(struct msg_head **message);
  36. int checksend(void);
  37. int con_act_resp(word msg_nr, word plci);
  38. int con_b3_act_resp(word msg_nr, word ncci);
  39. int con_b3_req(word plci, byte *ncpi);
  40. int con_b3_resp(word msg_nr, word ncci, byte reject, byte *ncpi);
  41. int con_resp(word msg_nr, word plci, byte reject);
  42. int dat_b3_resp(word msg_nr, word ncci, byte number);
  43. int discon_b3_req(word ncci, byte * ncpi);
  44. int discon_b3_resp(word msg_nr, word ncci);
  45. int discon_req(word plci, byte cause);
  46. int discon_resp(word msg_nr, word plci);
  47. int inf_resp(word msg_nr, word plci);
  48. int listen_b3_req(word plci);
  49. int sel_b2_prot_req(word plci, byte prot, byte * dlpd);
  50. int sel_b3_prot_req(word plci, byte prot, byte * ncpd);
  51. void PassUp(byte * buf, word len);
  52. void free_sendbuf(byte ind, word err);
  53. void pass_up_info(byte *p, byte s);
  54. void startsend(void);
  55. void check_buf(void);
  56. void do_api_int(void);
  57.  
  58. word
  59. get_Ncci(void)
  60. {
  61.     if(send_state >= IDLE)
  62.     {
  63.         SendDir= 0; /* ACTIVE */
  64.         Ncci= send_ncci;
  65.         return(SendState= send_state);
  66.     }
  67.     if(rcv_state >= IDLE)
  68.     {
  69.         SendDir= 1; /* PASSIVE */
  70.         Ncci= rcv_ncci;
  71.         return(SendState= rcv_state);
  72.     }
  73.     if(send_state >= DIAL)
  74.         return(SendState= send_state);
  75.     if(rcv_state >= CALLED)
  76.         return(SendState= rcv_state);
  77.  
  78.     if(SendState==DIAL) return(DIAL);
  79.     Ncci= 0;
  80.     return(SendState= 0);
  81. }
  82.  
  83. static word
  84. reset_plci(long p)
  85. {
  86.     if(p == send_plci)
  87.     {
  88.         send_plci= -1;
  89.         send_ncci= 0xffff;
  90.         send_state= DISCON;
  91.     }
  92.     if(p == rcv_plci)
  93.     {
  94.         rcv_plci= -1;
  95.         rcv_ncci= 0xfffe;
  96.         rcv_state= DISCON;
  97.     }
  98.     get_Ncci();
  99.     return (word) p;
  100. }
  101.  
  102. static word
  103. iserr(struct msg_head *p, int i, int m)
  104. {
  105.     word *s;
  106.     s= (word *) &p->data[i];
  107.     if(m && *s) printf("API err %x in msg %x %x\n",*s,p->command,p->subcommand);
  108.     return(*s);
  109. }
  110.  
  111. static void
  112. badstate(struct msg_head *p)
  113. {
  114.     printf("API bad state msg %x %x\n",p->command,p->subcommand);
  115. }
  116.  
  117. void
  118. apiint(void)
  119. {
  120.     is_api_int++;
  121.     if(PollInt) api_int_mark++;
  122.     else do_api_int();
  123.     is_api_int--;
  124. }
  125.  
  126. void
  127. do_api_int(void)
  128. {
  129.     struct msg_head *p;
  130.     word pl;
  131.  
  132.     if((api_get_message(&p) == 0) && p)
  133.     {
  134.         switch(p->command)
  135.         {
  136.         case 2: /* CONNECT */
  137.             switch(p->subcommand)
  138.             {
  139.             case 1: /* CONF word plci word info */
  140.                 status_line[70]='D';
  141.                 pl= *((word *) p->data);
  142.                 if(iserr(p,2,0))
  143.                 {
  144.                     if(SendState==DIAL) SendState=DISCON;
  145.                     reset_plci(pl);
  146.                     break;
  147.                 }
  148.                 send_plci= pl;
  149.                 if(send_state < CONNECT) send_state= CONNECT;
  150.                 break;
  151.             case 2: /* IND word plci byte contr. byte req. Serv
  152.                   byte req. Serv. add. byte eaz struct caller addr. */
  153.                 status_line[70]='I';
  154.                 pl= *((word *) p->data);
  155.                 if(accept_con_ind(p->data[3],p->data[4],p->data[5],
  156.                     (struct telno *)&p->data[6]))
  157.                 {
  158.                     if(rcv_state < CALLED) rcv_state= CALLED;
  159.                     rcv_plci= pl;
  160.                     rcv_ind_msg_nr= p->msg_nr;
  161.                     sel_b2_prot_req(pl,protokoll,(byte *) &dlpd);
  162.                     break;
  163.                 }
  164.                 discon_req(reset_plci(pl),0);
  165.             }
  166.             break;
  167.  
  168.         case 3: /* CONNECT ACTIVE word plci struct con_addr */
  169.             if(p->subcommand == 2)
  170.             {
  171.                 pl= *((word *) p->data);
  172.                 con_act_resp(p->msg_nr,pl);
  173.                 if((rcv_state >= CALLED) && (rcv_plci == pl)) break;
  174.                 send_plci= pl;
  175.                 if(send_state < CONNECT) send_state= CONNECT;
  176.                 sel_b2_prot_req(pl,protokoll,(byte *) &dlpd);
  177.             }
  178.             break;
  179.  
  180.         case 4: /* DISCONNECT */
  181.             pl= *((word *) p->data);
  182.             {
  183.                 int i;
  184.                 for(i=30; i<80; i++) status_line[i]=' ';
  185.             }
  186.             switch(p->subcommand)
  187.             {
  188.             case 1: /* CONF word plci word info */
  189.                 if(iserr(p,2,0)) reset_plci(pl);
  190.                 break;
  191.             case 2: /* IND word plci word info */
  192.                 if((pl==send_plci)&&(SendState==DIAL))
  193.                     SendState=DISCON;
  194.                 discon_resp(p->msg_nr,reset_plci(pl));
  195.                 check_buf();
  196.                 startsend();
  197.             }
  198.             break;
  199.  
  200.         case 5: /* LISTEN */
  201.             if(p->subcommand == 1) /* CONF byte contr word info */
  202.             {
  203.                 ListenErr= iserr(p,1,1);
  204.                 CheckListen= 0;
  205.             }
  206.             break;
  207.  
  208.         case 7: /* INFO */
  209.             switch(p->subcommand)
  210.             {
  211.             case 1: /* CONF word plci word info */
  212.                 iserr(p,2,1);
  213.                 break;
  214.             case 2: /* IND word plci word inf-no struc inf-element */
  215.                 pass_up_info(p->data,send_state>ISDISCON);
  216.                 inf_resp(p->msg_nr,*((word *) p->data));
  217.             }
  218.             break;
  219.  
  220.         case 0x40: /* SELECT B2 PROTOCOL */
  221.             status_line[70]='2';
  222.             if(p->subcommand == 1) /* CONF word plci word info */
  223.             {
  224.                 pl= *((word *) p->data);
  225.                 if(iserr(p,2,1))
  226.                 {
  227.                     discon_req(reset_plci(pl),0);
  228.                     break;
  229.                 }                
  230.                 sel_b3_prot_req(pl,4,nullstruct);
  231.             }
  232.             break;
  233.  
  234.         case 0x80: /* SELECT B3 PROTOCOL */
  235.             status_line[70]='3';
  236.             if(p->subcommand == 1) /* CONF word plci word info */
  237.             {
  238.                 pl= *((word *) p->data);
  239.                 if(iserr(p,2,1))
  240.                 {
  241.                     discon_req(reset_plci(pl),0);
  242.                     break;
  243.                 }                
  244.                 if(pl == send_plci) con_b3_req(pl,nullstruct);
  245.                 else if(pl == rcv_plci) listen_b3_req(pl);
  246.                 else badstate(p);
  247.             }
  248.             break;
  249.  
  250.         case 0x81: /* LISTEN B3 */
  251.             if(p->subcommand == 1) /* CONF word plci word info */
  252.             {
  253.                 pl= *((word *) p->data);
  254.                 if(iserr(p,2,1))
  255.                 {
  256.                     discon_req(reset_plci(pl),0);
  257.                     break;
  258.                 }
  259.                 con_resp(rcv_ind_msg_nr,pl,0);
  260.             }
  261.             break;
  262.  
  263.         case 0x82: /* CONNECT B3 */
  264.             status_line[70]='C';
  265.             switch(p->subcommand)
  266.             {
  267.             case 1: /* CONF word plci word ncci word info */
  268.                 pl= *((word *) p->data);
  269.                 if(iserr(p,4,1))
  270.                 {
  271.                     discon_req(reset_plci(pl),0);
  272.                     break;
  273.                 }                
  274.                 if(pl == send_plci)
  275.                 {
  276.                     send_ncci= *((word *) &p->data[2]);
  277.                     if(send_state < CONNECT) send_state= CONNECT;
  278.                 }
  279.                 else badstate(p);
  280.                 break;
  281.             case 2: /* IND word ncci word plci struct ncpi */
  282.                 pl= *((word *) &p->data[2]);
  283.                 if(pl == rcv_plci)
  284.                 {
  285.                     rcv_ncci= *((word *) p->data);
  286.                     con_b3_resp(p->msg_nr,rcv_ncci,0,nullstruct);
  287.                     if(rcv_state < CONNECT) rcv_state= CONNECT;
  288.                 }
  289.                 else badstate(p);
  290.             }
  291.             break;
  292.  
  293.         case 0x83: /* CONNECT B3 ACTIVE */
  294.             status_line[70]='C';
  295.             if(p->subcommand == 2) /* IND word ncci struct ncpi */
  296.             {
  297.                 word n;
  298.                 n= *((word *) p->data);
  299.                 con_b3_act_resp(p->msg_nr,n);
  300.                 if((send_plci != -1) && (n == send_ncci)&& (send_state < IDLE))
  301.                     send_state= IDLE;
  302.                 if((rcv_plci != -1 ) && (n == rcv_ncci) && (rcv_state < IDLE))
  303.                     rcv_state= IDLE;
  304.                 startsend();
  305.                 if((send_state >= IDLE)&&(rcv_state >= CONNECT))
  306.                     discon_b3_req(rcv_ncci,nullstruct);
  307.             }
  308.             break;
  309.  
  310.         case 0x84: /* DISCONNECT B3 */
  311.             switch(p->subcommand)
  312.             {
  313.             case 1: /* CONF word ncci word info */
  314.                 {
  315.                     word n;
  316.                     n= *((word *) p->data);
  317.                     if(iserr(p,2,0))
  318.                     {
  319.                         if((send_plci != -1) && (n == send_ncci))
  320.                             discon_req(reset_plci(send_plci),0);
  321.                         else if((rcv_plci != -1) && (n == rcv_ncci))
  322.                             discon_req(reset_plci(rcv_plci),0);
  323.                         break;
  324.                     }
  325.                     if(n == send_ncci) send_state= ISDISCON;
  326.                     else if(n == rcv_ncci) rcv_state= ISDISCON;
  327.                     get_Ncci();
  328.                 }
  329.                 break;
  330.             case 2: /* IND word ncci word info struct ncpi */
  331.                 {
  332.                     word n;
  333.                     n= *((word *) p->data);
  334.                     discon_b3_resp(p->msg_nr,n);
  335.                     if(n == send_ncci)
  336.                     {
  337.                         send_state= ISDISCON;
  338.                         discon_req(reset_plci(send_plci),0);
  339.                     }
  340.                     else if(n == rcv_ncci)
  341.                     {
  342.                         rcv_state= ISDISCON;
  343.                         discon_req(reset_plci(rcv_plci),0);
  344.                     }
  345.                 }
  346.             }
  347.             break;
  348.  
  349.         case 0x86: /* DATA B3 */
  350.             LastActTime= Tick;
  351.             switch(p->subcommand)
  352.             {
  353.             case 1: /* CONF word ncci byte number word info */
  354.                 status_line[71]='*';
  355.                 free_sendbuf(p->data[2],iserr(p,3,0));
  356.                 startsend();
  357.                 break;
  358.             case 2: /* IND word ncci word data-length dword data
  359.                   byte number word flags */
  360.                 status_line[72]='*';
  361.                 {
  362.                     word ps, l;
  363.                     byte far *pp;
  364.                     ps= get_prot_size();
  365.                     pp=(byte *) *((dword *) & p->data[4]);
  366.                     l=*((word *) & p->data[2]);
  367.                     PassUp(pp+ps, l-ps);
  368.                     dat_b3_resp(p->msg_nr,*((word *) p->data),p->data[8]);
  369.                 }
  370.             }
  371.             break;
  372.         default: badstate(p);
  373.         }
  374.     }
  375. }
  376.  
  377. void
  378. print_head(void)
  379. {
  380.     extern byte far *Crtat;
  381.     extern word line;
  382.     int i,j;
  383.     for(i=0,j=line;i<80;i++,j+=2) Crtat[j]=status_line[i];
  384.     status_line[71]= status_line[72]= ' ';
  385. }
  386.  
  387. InterruptPtr SaveTimerInt;
  388. word DisTimeout= 10*HZ;
  389. static dword NextCheck= 5*HZ;
  390.  
  391.  
  392. void TimerTick(void)
  393. {
  394.     is_api_int++;
  395.     
  396.     if(api_int_mark)
  397.     {
  398.         do_api_int();
  399.         api_int_mark--;
  400.     }
  401.     if(++Tick > NextCheck)
  402.     {
  403.         NextCheck= Tick + HZ;
  404.         if(DisTimeout && LastActTime && (Tick > (LastActTime + DisTimeout)))
  405.         {
  406.             LastActTime= 0;
  407.             if(rcv_state > ISDISCON)
  408.             {
  409.                 rcv_state= ISDISCON;
  410.                 discon_b3_req(rcv_ncci,nullstruct);
  411.             }
  412.             if(send_state > ISDISCON)
  413.             {
  414.                 send_state= ISDISCON;
  415.                 discon_b3_req(send_ncci,nullstruct);
  416.             }
  417.         }
  418.         if(headline) print_head();
  419.     }
  420.  
  421.     /* chain on old interrupt handler */
  422.     (*SaveTimerInt)();
  423.     is_api_int--;
  424. }
  425.  
  426.  
  427. word check_listen()
  428. {
  429.     while((Tick < 450) && CheckListen);
  430.     return(ListenErr);
  431. }
  432.  
  433. int check_con()
  434. {
  435.     if(send_plci== -1) return 0;
  436.     discon_req(reset_plci(send_plci),0);
  437.     return 1;
  438. }
  439.  
  440.