/***********************************************************************
 * 
 *  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 _CCHANNEL_
#define _CCHANNEL_

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

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

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

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

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

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

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

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

// Forward reference
class ClientReq;

//
// CChannel Class Definition
//
class CChannel : public ObjRef
{
   // Object State
   enum ChannelStates
   {
      State_Uninitialized = 1,
      State_FailedInitialization,
      State_Connected,
      State_Disconnected,
      State_Closed
   };
   ChannelStates        m_state;

   // Connection socket
   int                  m_socket;

   // Connection addresses
   struct sockaddr_in   m_remoteAddrIn;
   struct sockaddr_un   m_remoteAddrUn;
   bool                 m_useTcpSocket;

   // ReqId Allocator
   uint32_t             m_reqIdAllocator;

   // Synchronization variables
   pthread_mutex_t      m_mutex;

   //
   // Client Request Map - This map contains all of the active ClientReq objects.
   //                      The key used to obtain ClientReq object in the map
   //                      is the Request Id.
   //
   typedef map<uint32_t, ClientReq*> RCMap;
   typedef RCMap::iterator RCMapIter;
   typedef pair<RCMapIter, bool> RCIterBoolPair;
   RCMap                m_rcMap;

   //
   // Service connection thread procedure
   //
   // Parameters:
   //    pSmartCChannel (input) -
   //       Pointer to SmartPtr<CChannel> object.
   //
   // Abstract: Thread in charge of servicing channel connection.
   //
   // Returns: Nothing.
   //
   static void* connectionThread(SmartPtr<CChannel> *pSmartCChannel);

   //
   // Open socket routine
   //
   // Parameters: None.
   //
   // Abstract: Opens CChannel object socket.
   //
   // Returns: Nothing.
   //
   void openSocket(void);

   //
   // Connect socket routine
   //
   // Parameters: None.
   //
   // Abstract: Connects the CChannel object socket.
   //
   // Returns: Socket connect operation return status.
   //
   int connectSocket(void);

public:

   //
   // Constructor
   //
   // Parameters:
   //    remoteAddress (input) -
   //       Reference to sockaddr_in structure containing the remote
   //       endpoint address.
   //
   // Abstract: Constructs CChannel object.
   //
   // Returns: Nothing.
   //
   CChannel(struct sockaddr_in *remoteAddress);

   //
   // Constructor
   //
   // Parameters:
   //    remoteAddress (input) -
   //       Reference to sockaddr_un structure containing the remote
   //       endpoint address.
   //
   // Abstract: Constructs CChannel object.
   //
   // Returns: Nothing.
   //
   CChannel(struct sockaddr_un *remoteAddress);

   //
   // Destructor
   ~CChannel(void);

   //
   // Initialization routine
   //
   // Parameters: None.
   //
   // Abstract: Initializes CChannel object.
   //
   // Returns: 0 if successful.
   //
   int init(void);

   //
   // Close channel routine
   //
   // Parameters: None.
   //
   // Abstract: Closes the channel.
   //
   // Returns: Nothing.
   //
   void closeChannel(void);

   //
   // Check channel status routine.
   //
   // Parameters: None.
   //
   // Abstract: Checks if the channel status is OK
   //
   // Returns: True if the channel status is OK.
   //
   bool ok(void);

   //
   // Allocate Request Id routine
   //
   // Parameters: None.
   //
   // Abstract: Closes the channel.
   //
   // Returns: Allocated Request Id.
   //
   uint32_t allocReqId(void);

   //
   // Submit Request routine
   //
   // Parameters:
   //    reqId (input) -
   //       Id of the Request.
   //       
   //    clientReq (input) -
   //       Reference to ClientReq object.
   //
   //    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.
   //
   // Abstract: Submits a Request.
   //
   // Returns: 0 if successful.
   //
   int submitReq(uint32_t reqId,
                 ClientReq &clientReq,
                 char *pClientData,
                 uint32_t clientDataLen);

   //
   // Remove Request routine
   //
   // Parameters:
   //    reqId (input) -
   //       Id of the Request.
   //       
   // Abstract: Removes a Request from the channel.
   //
   // Returns: Nothing.
   //
   void removeReq(uint32_t reqId);

};
typedef SmartPtr<CChannel> SmartCChannel;


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


#endif // _CCHANNEL_

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