home *** CD-ROM | disk | FTP | other *** search
/ Oracle Video Server 3.0.3.1 / OVS_3031_NT.iso / win32 / sqlnet / net23 / client / fsm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-12-27  |  7.5 KB  |  200 lines

  1. /*
  2.   $Header: /netrcs/RCS/oracle/network/tns/tnsapi/RCS/fsm.c,v 1.4 1995/09/13 06:46:27 yzheng Exp $
  3. */
  4.  
  5.  
  6. /*
  7.  * Finite State Machines
  8.  */
  9. #include "tftpdef.h"
  10.  
  11. #ifdef CLIENT
  12. int recv_ACK(), recv_DATA(), recv_RQERR();
  13. #endif
  14.  
  15. #ifdef SERVER
  16. int recv_RRQ(), recv_WRQ(), recv_ACK(), recv_DATA(), recv_DISRQ();
  17. #endif
  18.  
  19. int fsm_error(), fsm_invalid();
  20.  
  21. /*
  22.  * Finite state machine table
  23.  * This is a 2-d array indexed by the last opcode sent and the opcode
  24.  * just received. The result is the address of a function to call to
  25.  * process the received opcode.
  26.  */
  27.  
  28. int (*fsm_ptr [OP_MAX+1][OP_MAX+1] ) () = 
  29. {
  30. #ifdef CLIENT
  31.   fsm_invalid,   /*  [sent = 0]             [recv = 0]                  */
  32.   fsm_invalid,   /*  [sent = 0]             [recv = OP_RRQ]             */
  33.   fsm_invalid,   /*  [sent = 0]             [recv = OP_WRQ]             */
  34.   fsm_invalid,   /*  [sent = 0]             [recv = OP_DATA]            */
  35.   fsm_invalid,   /*  [sent = 0]             [recv = OP_ACK]             */
  36.   fsm_invalid,   /*  [sent = 0]             [recv = OP_ERROR]           */
  37.  
  38.   fsm_invalid,   /*  [sent = OP_RRQ]        [recv = 0]           */
  39.   fsm_invalid,   /*  [sent = OP_RRQ]        [recv = OP_RRQ]      */
  40.   fsm_invalid,   /*  [sent = OP_RRQ]        [recv = OP_WRQ]      */
  41. recv_DATA,       /*  [sent = OP_RRQ]        [recv = OP_DATA]     */
  42.   fsm_invalid,   /*  [sent = OP_RRQ]        [recv = OP_ACK]      */
  43. recv_RQERR,      /*  [sent = OP_RRQ]        [recv = OP_ERROR]    */
  44.  
  45.   fsm_invalid,   /*  [sent = OP_WRQ]        [recv = 0 ]     */
  46.   fsm_invalid,   /*  [sent = OP_WRQ]        [recv = OP_RRQ]     */
  47.   fsm_invalid,   /*  [sent = OP_WRQ]        [recv = OP_WRQ]     */
  48.   fsm_invalid,   /*  [sent = OP_WRQ]        [recv = OP_DATA]     */
  49. recv_ACK,        /*  [sent = OP_WRQ]        [recv = OP_ACK]     */
  50. recv_RQERR,   /*  [sent = OP_WRQ]        [recv = OP_ERROR]     */
  51.  
  52.   fsm_invalid,   /*  [sent = OP_DATA]        [recv = 0]     */
  53.   fsm_invalid,   /*  [sent = OP_DATA]        [recv = OP_RRQ]     */
  54.   fsm_invalid,   /*  [sent = OP_DATA]        [recv = OP_WRQ]     */
  55.   fsm_invalid,   /*  [sent = OP_DATA]        [recv = OP_DATA]     */
  56. recv_ACK,   /*  [sent = OP_DATA]        [recv = OP_ACK]     */
  57.   fsm_error,   /*  [sent = OP_DATA]        [recv = OP_ERROR]     */
  58.  
  59.   fsm_invalid,   /*  [sent = OP_ACK]        [recv = 0]     */
  60.   fsm_invalid,   /*  [sent = OP_ACK]        [recv = OP_RRQ]     */
  61.   fsm_invalid,   /*  [sent = OP_ACK]        [recv = OP_WRQ]     */
  62. recv_DATA,       /*  [sent = OP_ACK]        [recv = OP_DATA]     */
  63.   fsm_invalid,   /*  [sent = OP_ACK]        [recv = OP_ACK]     */
  64.   fsm_error,   /*  [sent = OP_ACK]        [recv = OP_ERROR]     */
  65.  
  66.   fsm_invalid,   /*  [sent = OP_ERROR]        [recv = 0]     */
  67.   fsm_invalid,   /*  [sent = OP_ERROR]        [recv = OP_RRQ]     */
  68.   fsm_invalid,   /*  [sent = OP_ERROR]        [recv = OP_WRQ]     */
  69.   fsm_invalid,   /*  [sent = OP_ERROR]        [recv = OP_DATA]     */
  70.   fsm_invalid,   /*  [sent = OP_ERROR]        [recv = OP_ACK]     */
  71.   fsm_error   /*  [sent = OP_ERROR]        [recv = OP_ERROR]     */
  72. #endif /* CLIENT */
  73.  
  74. #ifdef SERVER
  75.   fsm_invalid,   /*  [sent = 0]        [recv = 0]     */
  76. recv_RRQ,        /*  [sent = 0]        [recv = OP_RRQ]     */
  77. recv_WRQ,        /*  [sent = 0]        [recv = OP_WRQ]     */
  78.   fsm_invalid,   /*  [sent = 0]        [recv = OP_DATA]     */
  79.   fsm_invalid,   /*  [sent = 0]        [recv = OP_ACK]     */
  80.   fsm_invalid,   /*  [sent = 0]        [recv = OP_ERROR]     */
  81.  
  82.   fsm_invalid,   /*  [sent = OP_RRQ]        [recv = 0]     */
  83.   fsm_invalid,   /*  [sent = OP_RRQ]        [recv = OP_RRQ]     */
  84.   fsm_invalid,   /*  [sent = OP_RRQ]        [recv = OP_WRQ]     */
  85.   fsm_invalid,   /*  [sent = OP_RRQ]        [recv = OP_DATA]     */
  86.   fsm_invalid,   /*  [sent = OP_RRQ]        [recv = OP_ACK]     */
  87.   fsm_invalid,   /*  [sent = OP_RRQ]        [recv = OP_ERROR]     */
  88.  
  89.   fsm_invalid,   /*  [sent = OP_WRQ]        [recv = 0]     */
  90.   fsm_invalid,   /*  [sent = OP_WRQ]        [recv = OP_RRQ]     */
  91.   fsm_invalid,   /*  [sent = OP_WRQ]        [recv = OP_WRQ]     */
  92.   fsm_invalid,   /*  [sent = OP_WRQ]        [recv = OP_DATA]     */
  93.   fsm_invalid,   /*  [sent = OP_WRQ]        [recv = OP_ACK]     */
  94.   fsm_invalid,   /*  [sent = OP_WRQ]        [recv = OP_ERROR]     */
  95.  
  96.   fsm_invalid,   /*  [sent = OP_DATA]       [recv = 0]     */
  97.   fsm_invalid,   /*  [sent = OP_DATA]       [recv = OP_RRQ]     */
  98.   fsm_invalid,   /*  [sent = OP_DATA]       [recv = OP_WRQ]     */
  99.   fsm_invalid,   /*  [sent = OP_DATA]       [recv = OP_DATA]     */
  100. recv_ACK,        /*  [sent = OP_DATA]       [recv = OP_ACK]     */
  101.   fsm_error,     /*  [sent = OP_DATA]       [recv = OP_ERROR]     */
  102.  
  103.   fsm_invalid,   /*  [sent = OP_ACK]       [recv = 0]     */    
  104.   fsm_invalid,   /*  [sent = OP_ACK]       [recv = OP_RRQ]     */    
  105.   fsm_invalid,   /*  [sent = OP_ACK]       [recv = OP_WRQ]     */    
  106. recv_DATA,       /*  [sent = OP_ACK]       [recv = OP_DATA]     */    
  107.   fsm_invalid,   /*  [sent = OP_ACK]       [recv = OP_ACK]     */    
  108.   fsm_error,   /*  [sent = OP_ACK]       [recv = OP_ERROR]     */    
  109.  
  110.   fsm_invalid,   /*  [sent = OP_ERROR]       [recv = 0]     */    
  111.   fsm_invalid,   /*  [sent = OP_ERROR]       [recv = OP_RRQ]     */    
  112.   fsm_invalid,   /*  [sent = OP_ERROR]       [recv = OP_WRQ]     */    
  113.   fsm_invalid,   /*  [sent = OP_ERROR]       [recv = OP_DATA]     */    
  114.   fsm_invalid,   /*  [sent = OP_ERROR]       [recv = OP_ACK]     */    
  115.   fsm_invalid   /*  [sent = OP_ERROR]       [recv = OP_ERROR]     */    
  116. #endif /* SERVER */
  117. };
  118.     
  119.  
  120. /*
  121.  * Main loop of finite state machine
  122.  *
  123.  * For the client, we are called after either a RRQ or a WRQ has been sent
  124.  * to the other side.
  125.  *
  126.  * For the server, we are called after either a RRQ or a WRQ has been 
  127.  * received from the other side. In this case, the argument will be a 0
  128.  * (since nothing has been sent ) but the state table above handles this
  129.  */
  130.  
  131. int fsm_loop(opcode)
  132. int opcode;
  133. {
  134.   register int nbytes;
  135.  
  136.   op_sent = opcode;
  137.  
  138.   for (;;)
  139.   {
  140.     if ((nbytes = net_recv(recvbuff, MAXBUFF)) < 0)
  141.       err_dump("net_recv error");
  142.  
  143.     /*
  144.      * The shortest packet is the disconnect packet, only has two bytes
  145.      */
  146.     if (nbytes < 2)
  147.       err_dump("receive length = %d bytes", nbytes);
  148.     op_recv = ldshort(recvbuff);
  149.     if (op_recv < OP_MIN || op_recv > OP_MAX)
  150.     {
  151. #ifdef SERVER
  152.       if (op_recv == OP_DISCONNECT)
  153.       {
  154.         /* disconnect and exit */
  155.         tnsclose(&svrtnshdl);
  156.         exit(0);
  157.       }
  158.       else
  159. #endif
  160.         err_dump("invalid opcode received: %d", op_recv);
  161.     }
  162.  
  163.     /*
  164.      * we call the appropriate function, passing the address of the receive
  165.      * buffer and its length. These arguments ignore the received-opcode, 
  166.      * which we have already processed
  167.      * we assume that the called function will send a response to the
  168.      * other side. It is the called function's responsibility to 
  169.      * set op_sent to the op-code that it sends to the other side
  170.      */
  171.  
  172.     if ((*fsm_ptr[op_sent][op_recv])(recvbuff +2, nbytes -2) < 0)
  173.     {
  174.       /*
  175.        * when the called function return -1, this loop is done.
  176.        * e.g., RRQ or WRQ failed
  177.        */
  178. #ifndef WIN32
  179.       signal(SIGALRM, SIG_DFL);
  180. #endif
  181.       return(0);
  182.     }
  183.   }
  184. }
  185.  
  186. int fsm_error(ptr, nbytes)
  187. char *ptr;
  188. int nbytes;
  189. {
  190.   err_dump("error received: op_sent = %d, op_recv = %d", op_sent, op_recv);
  191. }
  192.  
  193. int fsm_invalid(ptr, nbytes)
  194. char *ptr;
  195. int nbytes;
  196. {
  197.   err_dump("protocol error: op_sent = %d, op_recv = %d", op_sent, op_recv);
  198. }
  199.  
  200.