/*******************************************************************

Copyright (c) 2004 Open Mobile Alliance, Ltd.  All Rights Reserved.

This software is made available under the usage and distribution terms 
covered by the Common Public License 1.0 and by using this software you
are bound by the terms and conditions of the same.

EXCEPT AS EXPRESSLY SET FORTH IN THE COMMON PUBLIC LICENSE,
THIS PROGRAM IS PROVIDED ON AN "AS IS" BASIS, 
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, 
ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, 
MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
   
Each recipient is solely responsible for determining the 
appropriateness of using and distributing this program and assumes 
all risks associated with its exercise of rights under the Common 
Public License, including but not limited to the risks and 
costs of program errors, compliance with applicable laws, 
damage to or loss of data, programs or equipment, and 
unavailability or interruption of operations.

********************************************************************/
#ifndef XPT_TCP_H
#define XPT_TCP_H

#include "xpttypes.h"
#include "openssl/ssl.h"
#include "openssl/err.h"
#include "openssl/x509v3.h"

/******************************************************/
/*        TCP/IP services return values               */
/******************************************************/

// Berkeley compatible return values
#define  TCP_RC_ERROR              -2  // an internal error occurred
#define  TCP_RC_EOF                -1  // end of transmission
#define  TCP_RC_OK                  0

// Berkeley compatible return values
#define  TCP_RC_EWOULDBLOCK        35
#define  TCP_RC_EINPROGRESS        36
#define  TCP_RC_EALREADY           37
#define  TCP_RC_ENOTSOCK           38
#define  TCP_RC_EDESTADDRREQ       39
#define  TCP_RC_EMSGSIZE           40
#define  TCP_RC_EPROTOTYPE         41
#define  TCP_RC_ENOPROTOOPT        42
#define  TCP_RC_EPROTONOSUPPORT    43
#define  TCP_RC_ESOCKTNOSUPPORT    44
#define  TCP_RC_EOPNOTSUPP         45
#define  TCP_RC_EPFNOSUPPORT       46
#define  TCP_RC_EAFNOSUPPORT       47
#define  TCP_RC_EADDRINUSE         48
#define  TCP_RC_EADDRNOTAVAIL      49
#define  TCP_RC_ENETDOWN           50
#define  TCP_RC_ENETUNREACH        51
#define  TCP_RC_ENETRESET          52
#define  TCP_RC_ECONNABORTED       53
#define  TCP_RC_ECONNRESET         54
#define  TCP_RC_ENOBUFS            55
#define  TCP_RC_EISCONN            56
#define  TCP_RC_ENOTCONN           57
#define  TCP_RC_ESHUTDOWN          58
#define  TCP_RC_ETOOMANYREFS       59
#define  TCP_RC_ETIMEDOUT          60
#define  TCP_RC_ECONNREFUSED       61
#define  TCP_RC_ELOOP              62
#define  TCP_RC_ENAMETOOLONG       63
#define  TCP_RC_EHOSTDOWN          64
#define  TCP_RC_EHOSTUNREACH       65
#define  TCP_RC_ENOTEMPTY          66
#define  TCP_RC_EPROCLIM           67
#define  TCP_RC_EUSERS             68
#define  TCP_RC_EDQUOT             69
#define  TCP_RC_ESTALE             70
#define  TCP_RC_EREMOTE            71
#define  TCP_RC_EDISCON           101

#define  TCP_RC_OTHER              10  // an unknown error occurred.

// #ifdef _cplusplus
// extern "C" {
// #endif


typedef enum { TCP_FIREWALL_DIRECT, TCP_FIREWALL_PROXY, TCP_FIREWALL_SOCKS } TcpFirewallType_t;

typedef struct _tcp_firewall_info {
    TcpFirewallType_t type;
    StringBuffer_t    serverName;
    int               serverPort;
} TcpFirewallInfo_t, *TcpFirewallInfoPtr_t;


/********************/
/* Type definitions */
/********************/
typedef int TcpRc_t;
typedef long           Socket_t;
typedef Socket_t      *SocketPtr_t;


/**
 * FUNCTION: tcpOpenConnection
 *
 *  Generate a TCP/IP socket, establish a connection
 *  with the specified communication partner
 *
 * PRE-Condition:
 *  -
 *
 * POST-Condition:
 *  The communication has been established. The generates socket can be used to
 *  exchange data with the communication partner.
 *
 * IN: szPort, host address / port.
 *             - If the communication open mode is "c", the IP address
 *             (and optional the TCP/IP port) is specified here. Examples:
 *             If no TCP/IP port has been specified, the default port 80 is taken.
 *             "192.168.5.1" (use default port 80) or "192.168.5.2:81" (use port 81)
 *             - If the communication open mode is "s", this parameter denotes the TCP/IP
 *             port that is used for this connection. If the string is empty, the default
 *             port 80 is used. Examples: "" (use default port 80) or "81" (use port 81).
 *     pszOpenMode, communication flags. "c" denotes that a client socket is created, "s"
 *             specifies a server socket to be generated.
 *
 *
 * OUT:    pSocket, Generated TCP/IP socket.
 *
 * IN/OUT: -
 *
 * RETURN: TcpRc_t Return code. Refer to the return code list above for details.
 *
 */

TcpRc_t tcpOpenConnection (CString_t   pszPort,
                           SocketPtr_t pSocket,
                           CString_t   pszOpenMode);



TcpRc_t tcpOpenConnectionEx (CString_t            pszPort,
                             SocketPtr_t          pSocket,
                             CString_t            pszOpenMode,
                             TcpFirewallInfoPtr_t pFirewallInfo);

/**
 * FUNCTION: tcpOpenConnectionSSL
 *
 *  Generate a TCP/IP socket, establish a connection
 *  with the specified communication partner over SSL
 *
 * IN: szPort, host address / port.
 *             - If the communication open mode is "c", the IP address
 *             (and optional the TCP/IP port) is specified here. Examples:
 *             If no TCP/IP port has been specified, the default port 80 is taken.
 *             "192.168.5.1" (use default port 80) or "192.168.5.2:81" (use port 81)
 *             - If the communication open mode is "s", this parameter denotes the TCP/IP
 *             port that is used for this connection. If the string is empty, the default
 *             port 80 is used. Examples: "" (use default port 80) or "81" (use port 81).
 *     pszOpenMode, communication flags. "c" denotes that a client socket is created, "s"
 *             specifies a server socket to be generated.
 *
 *
 * OUT:    pSocket, Generated TCP/IP socket.
 *         ppCtx, Generated SSL context handler. 
 *         ppSSL, Generated SSL handler.
 *
 * IN/OUT: -
 *
 * RETURN: TcpRc_t Return code. Refer to the return code list above for details.
 *
 */
TcpRc_t tcpOpenConnectionSSL (CString_t   pszPort,
                              SocketPtr_t pSocket,
                              SSL_CTX**   ppCtx,
                              SSL**       ppSSL,
                              CString_t   pszOpenMode,
                              TcpFirewallInfoPtr_t pFirewallInfo);

/**
 * FUNCTION: tcpCloseConnection
 *
 *  Closes an open TCP/IP connection for both client and server socket.
 *
 * PRE-Condition:
 *  the specified socket has been generated before, in invokng the
 *  tcpOpenConnection() service
 *
 * POST-Condition:
 *  The communication has been dropped. System resources that have been assigned
 *  with the specified TCP/IP socket are freed.
 *
 * IN/OUT: pSocket, pointer to an open TCP/IP socket. The function resets the
 *  socket to an 'unused' state.
 *
 * RETURN: TcpRc_t Return code. Refer to the return code list above for details.
 *
 */

TcpRc_t tcpCloseConnection (SocketPtr_t pSocket);

/**
 * FUNCTION: tcpCloseConnectionSSL
 *
 *  Closes an open TCP/IP connection for both client and server socket over SSL.
 *
 * IN/OUT: pSocket, pointer to an open TCP/IP socket. The function resets the
 *  socket to an 'unused' state.
 *
 * IN:     pCtx, pointer to SSL context handler.
 *         pSSL, pointer to SSL handler.
 *
 * RETURN: TcpRc_t Return code. Refer to the return code list above for details.
 *
 */
TcpRc_t tcpCloseConnectionSSL (SocketPtr_t pSocket,
                               SSL_CTX*    pCtx,
                               SSL*        pSSL);

/**
 * FUNCTION: tcpWaitforConnections
 *
 *  Wait until a client has been connected to the open server socket specified.
 *
 * PRE-Condition:
 *  The specified socket has been opened in the server mode (that means,
 *  pszOpenMode was set to "s" when the socket has been created by a
 *  tcpOpenConnection () invocation)
 *
 * POST-Condition:
 *  A new socket has been generated and can be used to communicate with the client.
 *
 * IN: pSocket, pointer to an open TCP/IP server socket.
 *
 * OUT: pNewSocket, pointer to a socket variable that will be set by this function with
 *      the generated communication socket.
 *      pchSenderAddress, pointer to at least 24 Bytes of memory that will be updated
 *      by this function with the IP address of the client that connected.
 *      Example: "192.168.5.1"
 *
 * RETURN: TcpRc_t Return code. Refer to the return code list above for details.
 *
 */
TcpRc_t tcpWaitforConnections (SocketPtr_t    pSocket,
                               SocketPtr_t    pNewSocket,
                               StringBuffer_t pchSenderAddress);

/**
 * FUNCTION: tcpSendData
 *
 *  Send a block of data to the communication partner
 *
 * PRE-Condition:
 *  The specified socket has been created either by the service
 *  tcpWaitforConnections() (server mode), or by the service tcpOpenConnection ()
 *  (Client mode). A server socket generated by tcpOpenConnection () must not be
 *  used for this function.
 *
 * POST-Condition:
 *  The specified data are transmitted to the communication partner.
 *  If the communication was broken or terminated by the communication partner,
 *  a return code TCP_RC_EOF is returned.
 *
 * IN: pSocket, pointer to an open TCP/IP server socket.
 *     pbBuffer, pointer to an allocated chunk of memory that contain the
 *     data to be transmitted.
 *     cbBufferSize, size in Bytes of the data to be transmitted.
 *
 * RETURN: TcpRc_t Return code or transmission status.
 *
 */

TcpRc_t tcpSendData (SocketPtr_t        pSocket,
                     const DataBuffer_t pbBuffer,
                     BufferSize_t       cbBufferSize);

/**
 * FUNCTION: tcpSendDataSSL
 *
 *  Send a block of data to the communication partner over SSL.
 *
 * IN: pSocket, pointer to an open TCP/IP server socket.
 *     pbBuffer, pointer to an allocated chunk of memory that contain the
 *     data to be transmitted.
 *     cbBufferSize, size in Bytes of the data to be transmitted.
 *     pSSL, SSL handler.
 *
 * RETURN: TcpRc_t Return code or transmission status.
 *
 */
TcpRc_t tcpSendDataSSL (SocketPtr_t        pSocket,
                        SSL*               pSSL,
                        const DataBuffer_t pbBuffer,
                        BufferSize_t       cbBufferSize);

/**
 * FUNCTION: tcpReadData
 *
 *  Receive a block of data from the communication partner
 *
 * PRE-Condition:
 *  The specified socket has been created either by the service
 *  tcpWaitforConnections() (server mode), or by the service tcpOpenConnection ()
 *  (Client mode). A server socket generated by tcpOpenConnection () must not be
 *  used for this function.
 *
 * POST-Condition:
 *  The specified data are received from the communication partner.
 *  If the communication was broken or terminated by the communication partner,
 *  a return code TCP_RC_EOF is returned.
 *
 * IN:     pSocket, pointer to an open TCP/IP server socket.
 *         pbBuffer, pointer to an allocated chunk of memory that is filled up
 *         with the data that are received from the communication partner.
 * IN/OUT: pcbBufferSize, The parameter points to a variable that is set with the
 *         size in bytes of the data buffer by the caller. The function replaces
 *         this value with the length of the data block that has been received.
 *
 * RETURN: TcpRc_t Return code or transmission status.
 *         Refer to the return code list above for details.
 *
 */

TcpRc_t tcpReadData (SocketPtr_t     pSocket,
                     DataBuffer_t    pbBuffer,
                     BufferSizePtr_t pcbBufferSize);

/**
 * FUNCTION: tcpReadDataSSL
 *
 *  Receive a block of data from the communication partner over SSL.
 *
 * IN:     pSocket, pointer to an open TCP/IP server socket.
 *         pbBuffer, pointer to an allocated chunk of memory that is filled up
 *         with the data that are received from the communication partner.
 *         pSSL, SSL handler.
 * IN/OUT: pcbBufferSize, The parameter points to a variable that is set with the
 *         size in bytes of the data buffer by the caller. The function replaces
 *         this value with the length of the data block that has been received.
 *
 * RETURN: TcpRc_t Return code or transmission status.
 *         Refer to the return code list above for details.
 *
 */
TcpRc_t tcpReadDataSSL (SocketPtr_t     pSocket,
                        SSL*            pSSL,
                        DataBuffer_t    pbBuffer,
                        BufferSizePtr_t pcbBufferSize);


/**
 * FUNCTION: getSockIP
 *
 *  Retrieve the IP in dotted decimal corresponding to the  socket indcated
 *
 * PRE-Condition:
 *  The specified socket has been created either by the service
 *  tcpWaitforConnections() (server mode), or by the service tcpOpenConnection ()
 *  (Client mode). A multihomed server socket generated by tcpOpenConnection () must not be
 *  used for this function.
 *
 * POST-Condition:
 *  The ip address in dotted decimal format is retrieved in the pchAddr variable.
 *  The caller should not try to free the memmory location pointed by pchAddr;
 *
 * IN:     pSocket, pointer to an open TCP/IP server socket.
 * IN/OUT: pchAddr, Pointer to memory location where the  address of the
 *		   allocated ip address will be stored
 *
 * RETURN: Bool_t. Returns true if address is succesfully retrieved..
 *         Refer to the return code list above for details.
 *
 */

Bool_t getSockIP(SocketPtr_t pSocket,char** pchAddr);

// #ifdef _cplusplus
// }
// #endif

#endif
