home *** CD-ROM | disk | FTP | other *** search
/ Network Support Encyclopedia 96-1 / novell-nsepro-1996-1-cd2.iso / download / netware / dax1.exe / CP / CPS / CPSEND.C < prev    next >
Text File  |  1992-07-15  |  7KB  |  166 lines

  1. //   ╔════════════════════════════════════════════════════════════════════╗
  2. //   ║                                                                    ║
  3. //   ║ module:      cpsend.c                                              ║
  4. //   ║ abstract:    This module contains the support for sending messages ║
  5. //   ║              to client nodes.                                      ║
  6. //   ║                                                                    ║
  7. //   ║ environment: NetWare 3.x v3.11                                     ║
  8. //   ║              Network C for NLMs SDK                                ║
  9. //   ║              CLib v3.11                                            ║
  10. //   ║                                                                    ║
  11. //   ║  This software is provided as is and carries no warranty           ║
  12. //   ║  whatsoever.  Novell disclaims and excludes any and all implied    ║
  13. //   ║  warranties of merchantability, title and fitness for a particular ║
  14. //   ║  purpose.  Novell does not warrant that the software will satisfy  ║
  15. //   ║  your requirements or that the software is without defect or error ║
  16. //   ║  or that operation of the software will be uninterrupted.  You are ║
  17. //   ║  using the software at your risk.  The software is not a product   ║
  18. //   ║  of Novell, Inc. or any of subsidiaries.                           ║
  19. //   ║                                                                    ║
  20. //   ╟────────────────────────────────────────────────────────────────────╢
  21. //   ║ maintenance history:                                               ║
  22. //   ║ level    date      pi   description                                ║
  23. //   ╟────────────────────────────────────────────────────────────────────╢
  24. //   ║  001   01/29/92    kl   initial release.                           ║
  25. //   ╚════════════════════════════════════════════════════════════════════╝
  26.  
  27. #include <stdlib.h>
  28. #include <string.h>
  29. #include <nwmisc.h>
  30. #include <process.h>
  31. #include "cp/cpsys.h"
  32.  
  33. //------------------------------------------------------------------------
  34.  
  35. STATIC  CPCOMMDATA  sends[CPSNUMSENDELEM];
  36.  
  37. //------------------------------------------------------------------------
  38. //
  39. //  This API locates one of the 'send' structures that is free
  40. //
  41. STATIC  CPCOMMDATA  *CPFindFreeCPCommData()
  42. {
  43.         int     i;
  44.  
  45.         for(i=0; i < CPSNUMSENDELEM; ++i)
  46.             if(!sends[i].ecb.status || sends[i].ecb.status > 0xF000)
  47.                 return &sends[i];
  48.         DIAG3("CPFindFreeCPCommData() couldn't!");
  49.         return NULL;
  50. }
  51.  
  52. //------------------------------------------------------------------------
  53. //
  54. //  This API initializes a send ECB. i.e. readies it for transport...
  55. //
  56.  
  57. void    CPInitSendPacket(WORD  socket,          // socket to send on
  58.                     IPX_ECB    *ecb,            // the ecb
  59.                     IPX_HEADER *hdr,            // the ipx header
  60.                     void       *request,        // the data portion
  61.                     WORD       sizeRequest)     // the data portion size
  62. {
  63.         //
  64.         //  Note that since the socket is a parameter to the IPX CLIB
  65.         //  functions, it can be init'ed here, or simply passed via Send.
  66.         //  If you init here, then pass 0 when you call IpxSend...
  67.         //
  68.         ecb->socket                  = socket;
  69.         ecb->fragCount               = 2;
  70.         ecb->fragList[0].fragAddress = hdr;
  71.         ecb->fragList[0].fragSize    = sizeof( IPX_HEADER );
  72.         ecb->fragList[1].fragAddress = request;
  73.         ecb->fragList[1].fragSize    = sizeRequest;
  74.         hdr->packetType              = (char)4;
  75.         //
  76.         //  The remaining fields requiring initialization, will be filled
  77.         //  when a packet is sent. i.e. the destination net, node and socket
  78.         //  of the IPX header, and immediateAddress field of ECB.
  79.         //
  80. }
  81.  
  82. //------------------------------------------------------------------------
  83. //
  84. //  This API gets the CP Layer ready to send data to the client
  85. //
  86. T_RC    CPInitializeSendLogic()
  87. {
  88.         int     i;
  89.         //
  90.         //  Get all of our send structures ready for sending replies.
  91.         //
  92.         for(i=0; i < CPSNUMSENDELEM; ++i){
  93.             CPInitSendPacket(0,
  94.                              &sends[i].ecb,
  95.                              &sends[i].ipx,
  96.                              &sends[i].cpmsg,
  97.                              sizeof sends[i].cpmsg);
  98.         }
  99.         return CP_SUCCESS;
  100. }
  101.  
  102. //------------------------------------------------------------------------
  103. //
  104. //  This API sends a reply to the client
  105. //
  106. T_RC    CPSendMessage(UINT32 sessionID, void *data, unsigned length)
  107. {
  108.         LONG        tTime;
  109.         WORD        startTicks,endTicks;
  110.         CPCOMMDATA  *c = CPFindFreeCPCommData();
  111.         CPDATA      *p = CPGetClientInfo(sessionID);
  112.  
  113.         if( !p ) return CP_UNKNOWN_CLIENT;
  114.         if( !c ) return CP_TRANSPORT_BUSY;
  115.  
  116.         c->cpmsg.cphdr = p->cphdr;
  117.         memmove(c->cpmsg.msg,data,min(CPMAXMSG,length));
  118.         //
  119.         //  Set address of destination before sending...
  120.         //
  121.         *(InternetAddress *)&c->ipx.destNet = p->ipxaddr;
  122.         IpxGetLocalTarget((BYTE *)&c->ipx.destNet,&c->ecb, &tTime);
  123.         xDIAG4(CPprintf("CPSend: Sending to %08x:%08x%04x:%04x\n",
  124.                         LongSwap(c->ipx.destNet),
  125.                         LongSwap(*(LONG *)c->ipx.destNode),
  126.                         IntSwap(*(WORD *)&c->ipx.destNode[4]),
  127.                         IntSwap(c->ipx.destSocket)));
  128.         IpxSend(0,&c->ecb);
  129.         //
  130.         //  wait tTime for the packet to get onto the wire.
  131.         //
  132.         startTicks = GetCurrentTicks();         // read start time
  133.         while( c->ecb.status ){
  134.             ThreadSwitch();
  135.             endTicks = GetCurrentTicks();
  136.             //
  137.             //  Give it enough time to get there. Shouldn't take this
  138.             //  long to get it out on the wire...
  139.             //
  140.             if( endTicks - startTicks > tTime ){
  141.                 DIAG3("CPSendMessage() timed out!");
  142.                 break;
  143.             }
  144.         }
  145.         if( c->ecb.status ) DIAG3("CPSendMessage() couldn't!");
  146.         return c->ecb.status ? CP_TRANSPORT_ERROR : CP_SUCCESS;
  147. }
  148.  
  149. //------------------------------------------------------------------------
  150. //
  151. //  This API shuts the send logic down
  152. //
  153. T_RC    CPDeInitializeSendLogic()
  154. {
  155.         int     i;
  156.         //
  157.         //  Get all of our send structures ready for sending replies.
  158.         //
  159.         for(i=0; i < CPSNUMSENDELEM; ++i){
  160.             while( sends[i].ecb.status > 0 && sends[i].ecb.status < 0x7f )
  161.                 ThreadSwitch();
  162.         }
  163.         return CP_SUCCESS;
  164. }
  165. 
  166.