/***********************************************************************
 * 
 *  Copyright (C) 2006 Novell, Inc. All Rights Reserved.
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; version 2.1
 *  of the License.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Library Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, Novell, Inc.
 * 
 *  To contact Novell about this file by physical or electronic mail, 
 *  you may find current contact information at www.novell.com.
 * 
 *  Author: Juan Carlos Luciani <jluciani@novell.com>
 *
 ***********************************************************************/


#ifndef _REMOTEENDPOINT_
#define _REMOTEENDPOINT_

//===[ Include files ]=====================================================

//===[ External data ]=====================================================

//===[ External prototypes ]===============================================

//===[ Manifest constants ]================================================

#define  MAX_CHANNELS_PER_ENDPOINT  3

//===[ Type definitions ]==================================================

//===[ Function prototypes ]===============================================

//===[ Global variables ]==================================================

//===[ Type definitions ]==================================================

//
// Server Thread Class
//
class RemoteEndPoint : public ObjRef
{
   //
   // Class for maintaining SmartCChannel pointers within the daemonVector.
   //
   class SmartCChannelPointer
   {
   private:
         SmartCChannel *m_pSmartCChannel;
   public:
   
      SmartCChannelPointer() : m_pSmartCChannel(NULL) {}
      ~SmartCChannelPointer() { if (m_pSmartCChannel != NULL) delete m_pSmartCChannel; }
      SmartCChannel* getPointer() { return m_pSmartCChannel; }
      void setPointer(SmartCChannel *pSmartCChannel) { m_pSmartCChannel = pSmartCChannel; }
   };

   // Signature
   unsigned long           m_signature;

   // End-point address
   bool                    m_Use_AF_INET;
   bool                    m_Use_PF_UNIX;
   struct sockaddr_in      m_serverInAddr;
   struct sockaddr_un      m_serverUnAddr;

   // SmartCChannelPointers vector
   vector<SmartCChannelPointer> m_cchannelVector;
   int                     m_numCChannels;

   // Endpoint mutex
   pthread_mutex_t         m_mutex;

   // Number of submits made to the endpoint
   int                     m_numChannelSubmits;

   // Max number of Rpc retries
   int                     m_maxRpcRetries;

public:

   //
   // Destructor
   ~RemoteEndPoint(void);

   //
   // Constructor
   //
   // Parameters:
   //    multithreaded (input) -
   //       Set to TRUE if the process is
   //       multithreaded.
   // 
   //    maxRpcRetries (input) -
   //       Max Rpc retries.
   //
   //    pSocketFileName (input) -
   //       Pointer to string containing the name
   //      of the socket file.
   //
   // Abstract: Constructs RemoteEndPoint object and initializes it using
   //           a domain socket file name.
   //
   // Returns: Nothing.
   //
   RemoteEndPoint(bool multiThreaded,
                  int maxRpcRetries,
                  char *pSocketFileName);

   //
   // Constructor
   //
   // Parameters:
   //    multithreaded (input) -
   //       Set to TRUE if the process is
   //       multithreaded.
   // 
   //    maxRpcRetries (input) -
   //       Max Rpc retries.
   //
   //    port (input) -
   //       Server's listening port number.
   // 
   //    address (input) -
   //       The server's IP Address. Use
   //       0x7F000001 if the endpoint is local.
   //
   // Abstract: Constructs RemoteEndPoint object and initializes it using
   //           a tcp socket address.
   //
   // Returns: Nothing.
   //
   RemoteEndPoint(bool multiThreaded,
                  int maxRpcRetries,
                  unsigned short int port,
                  uint32_t address);

   //
   // Get a SmartCChannel.
   //
   // Parameters: None.
   //
   // Abstract: Gets a SmartCChannel for submitting requests to the
   //           remote endpoint.
   //
   // Returns: Pointer to SmartCChannel object if successful, otherwise
   //          NULL.
   //
   SmartCChannel *getCChannel(void);

   //
   // Submit a request to the endpoint,
   // 
   // Parameters:
   //    pClientData (input) -
   //       Pointer to client data that must be sent to
   //       the server. Buffer is NEVER released by the
   //       procedure.
   //
   //    clientDataLen (input) -
   //       Length of the client data.
   //
   //    ppServerData (input/output) -
   //       Pointer to variable that will receive a
   //       pointer to the buffer containing the data
   //       received from the server.
   //
   //    pServerDataLen (input/output) -
   //       Pointer to variable that will receive the
   //       length of the data received from the server.
   //
   // Abstract:      Method to submit a request.
   //
   // Returns: 0 == Request completed gracefully
   //          -1 == Request did not complete gracefully
   //
   // Note: The routine blocks until the request completes.
   //
   int submitReq(char *pClientData,
                 uint32_t clientDataLen,
                 char **ppServerData,
                 uint32_t *pServerDataLen);
};
typedef SmartPtr<RemoteEndPoint> SmartRemoteEndPoint;


//===[ Function prototypes ]===============================================


#endif // _REMOTEENDPOINT_

//=========================================================================
//=========================================================================