home *** CD-ROM | disk | FTP | other *** search
/ Network Support Encyclopedia 96-1 / novell-nsepro-1996-1-cd2.iso / download / netware / dax1.exe / DAP / DAPA / DAPSEND.C < prev    next >
Text File  |  1992-07-15  |  9KB  |  184 lines

  1. //   ╔════════════════════════════════════════════════════════════════════╗
  2. //   ║                                                                    ║
  3. //   ║ module:      dapsend.c                                             ║
  4. //   ║ abstract:    This module contains the code to send requests to     ║
  5. //   ║              our server application.  This routines is the 'guts'  ║
  6. //   ║              of the DAP Layer on the client side.  This is where   ║
  7. //   ║              we implement things like retries, sequencing, etc.    ║
  8. //   ║                                                                    ║
  9. //   ║ environment: NetWare 3.x v3.11                                     ║
  10. //   ║              Network C for NLMs SDK                                ║
  11. //   ║              CLib v3.11                                            ║
  12. //   ║              Network C for DOS v2.0                                ║
  13. //   ║              NetWare C Interface DOS v1.2                          ║
  14. //   ║                                                                    ║
  15. //   ║  This software is provided as is and carries no warranty           ║
  16. //   ║  whatsoever.  Novell disclaims and excludes any and all implied    ║
  17. //   ║  warranties of merchantability, title and fitness for a particular ║
  18. //   ║  purpose.  Novell does not warrant that the software will satisfy  ║
  19. //   ║  your requirements or that the software is without defect or error ║
  20. //   ║  or that operation of the software will be uninterrupted.  You are ║
  21. //   ║  using the software at your risk.  The software is not a product   ║
  22. //   ║  of Novell, Inc. or any of subsidiaries.                           ║
  23. //   ║                                                                    ║
  24. //   ╟────────────────────────────────────────────────────────────────────╢
  25. //   ║ maintenance history:                                               ║
  26. //   ║ level    date      pi   description                                ║
  27. //   ╟────────────────────────────────────────────────────────────────────╢
  28. //   ║  001   01/24/92    kl   initial release.                           ║
  29. //   ║  002   07/14/92    kl   windows port.  add a delay() for Windows   ║
  30. //   ╚════════════════════════════════════════════════════════════════════╝
  31.  
  32. #include    <stdio.h>
  33. #include    <conio.h>
  34. #include    <dos.h>
  35. #include    <time.h>
  36. #include    "cp/cpapi.h"
  37. #include    "dap/dapsys.h"
  38.  
  39. #if defined(WINCLIENT)
  40.  
  41. #define delay(x)    __dsdelay(x)
  42. extern void FAR PASCAL IPXYield(void);
  43.  
  44. void    __dsdelay(unsigned milliseconds)
  45. {
  46.         clock_t     start = clock();
  47.         unsigned    ticks = milliseconds / 55;
  48.         //
  49.         //  wrote this, since delay() isn't in Windows...
  50.         //
  51.         //  I'm approximating everything here, but this API really isn't
  52.         //  too important.  I will always wait at least 1 tick, regardless
  53.         //  of how many milliseconds you asked for.  I'm assuming that
  54.         //  there are 55 milliseconds in a clock tick...
  55.         //
  56.         while( (clock() - start) <= ticks ) IPXYield();
  57. }
  58.  
  59. #endif
  60.  
  61. T_RC    DAPSendRequest(DAPDATA *DAPid, UINT16 requestCode)
  62. {
  63.         WORD    RetryCount = DAPid->retryCount;
  64.         WORD    ResponseDelay;
  65.         //
  66.         //  Init the common DAP fields
  67.         //
  68.         DAPid->dapRequest.packetType  = DAPSERVICEREQUEST;
  69.         DAPid->dapRequest.sequence    = DAPid->nextSequence++;
  70.         DAPid->dapRequest.sessionID   = DAPid->sessionID;
  71.         DAPid->dapRequest.requestCode = requestCode;
  72.         //
  73.         //  Send the request, wait for a reply
  74.         //
  75.         DAPid->timesTried = 0;
  76.         DAPid->sendFailed = 0;
  77.         while( RetryCount-- ){
  78.             //
  79.             //  Try to send the message to the server
  80.             //
  81.             //  Let the DAP Layer on the server side know how many times
  82.             //  we've retried this request...
  83.             //
  84.             DAPid->dapRequest.timesTried = DAPid->timesTried++;
  85.             //!!
  86.             //  This can cause us to register twice, if the first packet
  87.             //  is lost somewhere.  If the server really registered us,
  88.             //  but we lost the reply, we will register again here...
  89.             //
  90.             //  If we made the server smart enought to handle this, however
  91.             //  and automatically handle this.  like maybe ignore the 2nd
  92.             //  request for the same thing, if the response hasn't yet
  93.             //  been sent.
  94.             //  
  95.             //  could make the server send an immediate reply back to the
  96.             //  client, telling him about this situation.  the client
  97.             //  could detect this, and provide some sort of intelligent
  98.             //  handling.
  99.             //  
  100.             //  have a constant (NUMBERTIMESTORETRYWHENBUSY) to control this.
  101.             //  
  102.             //  try a reset_router console command to try and force this
  103.             //  error!!!
  104.             //!!
  105.             if( CPSendMessage(DAPid->CPid,&DAPid->dapRequest,sizeof DAPid->dapRequest) ){
  106.                 DAPid->sendFailed++;
  107.                 continue;
  108.             }
  109.             //
  110.             //  Wait for a response to come in
  111.             //
  112.             ResponseDelay = DAPid->responseDelay;
  113.             while( ResponseDelay-- ){
  114.                 if( CPRecvMessage(DAPid->CPid,&DAPid->dapReply,sizeof DAPid->dapReply) == 0 ){
  115.                     switch(DAPid->dapReply.packetType){
  116.                     //
  117.                     //  A ServiceReply is what we are waiting for.  Just
  118.                     //  make sure the sequence number is correct.
  119.                     //
  120.                     case DAPSERVICEREPLY:
  121.                         //
  122.                         //  Make sure we got what we were expecting
  123.                         //
  124.                         if( DAPid->dapRequest.sequence != DAPid->dapReply.sequence ){
  125.                             xDIAG1(DAPprintf("\nGot %lx.  Expecting %lx.\n",
  126.                                              DAPid->dapReply.sequence,
  127.                                              DAPid->dapRequest.sequence));
  128.                             //!!return DAP_PACKET_OUT_OF_SEQ;
  129.                             //
  130.                             //  Let's just wait for the correct one...
  131.                             //
  132.                             break;
  133.                         }
  134.                         //!!
  135.                         //  If server is telling us that he is busy,
  136.                         //  retry without penalizing the response delay.
  137.                         //  can use the state info to determine if we 
  138.                         //  are not in the sending state.  if so, ignore
  139.                         //  packet.  !! cannot queue the reply, cause
  140.                         //  the links will be used by other threads!
  141.                         //  can have a STATEREPLY packet which can be
  142.                         //  expidited thru the system.  it would use
  143.                         //  a 'canned reply' to the client in question.
  144.                         //  don't reset the state until you know the
  145.                         //  reply has been sent, and then you'll know
  146.                         //  it is okay to accept another request!  This
  147.                         //  way, we can just print an information message
  148.                         //  saying we received a 'duplicate' request
  149.                         //  and go on.
  150.                         //  
  151.                         //!!
  152.                         return DAPid->dapReply.returnCode;
  153.                         break;
  154.                 #if 0
  155.                     //
  156.                     //  We'll need this later, when we allow the server
  157.                     //  to send requests to us...
  158.                     //
  159.                     //  A ServiceRequest has been received from the server.
  160.                     //  Pass this data off to the routine that can deal 
  161.                     //  with the request, and then look for our reply.
  162.                     //
  163.                     case DAPSERVICEREQUEST:
  164.                         DAPHandleServiceRequest((DAPRequest *)&DAPid->dapReply);
  165.                         break;
  166.                 #endif
  167.                     //
  168.                     //  We got something we weren't expecting...
  169.                     //
  170.                     default:
  171.                         return DAP_INTERNAL_ERROR;
  172.                         break;
  173.                     }
  174.                 }
  175.                 delay(112);       // wait just 2 ticks and try again
  176.             }
  177.             delay(112);           // wait before trying again
  178.         }
  179.         return (DAPid->sendFailed == DAPid->timesTried) 
  180.                     ? DAP_SEND_FAILURE 
  181.                     : DAP_TIMEOUT;
  182. }
  183.  
  184.