/*
 * Copyright (C) 1997-2003 by Objective Systems, Inc.
 *
 * This software is furnished under a license and may be used and copied
 * only in accordance with the terms of such license and with the
 * inclusion of the above copyright notice. This software or any other
 * copies thereof may not be provided or otherwise made available to any
 * other person. No title to and ownership of the software is hereby
 * transferred.
 *
 * The information in this software is subject to change without notice
 * and should not be construed as a commitment by Objective Systems, Inc.
 *
 * PROPRIETARY NOTICE
 *
 * This software is an unpublished work subject to a confidentiality agreement
 * and is protected by copyright and trade secret law.  Unauthorized copying,
 * redistribution or other use of this work is prohibited.
 *
 * The above notice of copyright on this source code product does not indicate
 * any actual or intended publication of such source code.
 *
 *****************************************************************************/

/** 
 * @file rtSocket.h 
 * Common runtime constants, data structure definitions, and run-time functions
 * to support the sockets' operations.
 */
#ifndef _RTSOCKET_H_
#define _RTSOCKET_H_

#include "asn1type.h"

#ifdef __cplusplus
extern "C" {
#endif

/** @defgroup socketstr Sockets' structures' definitions.
 * @ingroup comruntime 
 * @{
 */

#if defined (_WIN64)
typedef unsigned __int64 OSRTSOCKET; /**< Socket's handle */
#elif defined (_WIN32)
typedef unsigned int OSRTSOCKET; /**< Socket's handle */
#else
typedef int OSRTSOCKET;          /**< Socket's handle */
#endif

#define OSRTSOCKET_INVALID ((OSRTSOCKET)-1)

/** 
 * The IP address represented as unsigned long value. The most significant 8
 * bits in this unsigned long value represent the first number of the IP
 * address. The least significant 8 bits represent the last number of the IP
 * address.
 */
typedef unsigned long OSIPADDR;

#define OSIPADDR_ANY   ((OSIPADDR)0)
#define OSIPADDR_LOCAL ((OSIPADDR)0x7f000001UL) /* 127.0.0.1 */

/** @} */

/** @defgroup sockets Sockets' functions.
 * @ingroup comruntime 
 * @{
 */
/**
 * This function permits an incoming connection attempt on a socket. It
 * extracts the first connection on the queue of pending connections on socket.
 * It then creates a new socket and returns a handle to the new socket. The
 * newly created socket is the socket that will handle the actual connection
 * and has the same properties as original socket. See description of 'accept'
 * socket function for further details.
 *
 * @param socket       The socket's handle created by call to ::rtSocketCreate
 *                       function.
 * @param pNewSocket   The pointer to variable to receive the new socket's
 *                       handle.
 * @param destAddr     Optional pointer to a buffer that receives the IP
 *                       address of the connecting entity. It may be NULL.
 * @param destPort     Optional pointer to a buffer that receives the port of
 *                       the connecting entity. It may be NULL.
 * @return             Completion status of operation: 0 (ASN_OK) = success,
 *                       negative return value is error.
 */
EXTERNRT int rtSocketAccept (OSRTSOCKET socket, OSRTSOCKET *pNewSocket, 
                             OSIPADDR* destAddr, int* destPort);

/**
 * This function converts an IP address to its string representation.
 *
 * @param ipAddr       The IP address to be converted.
 * @param pbuf         Pointer to the buffer to receive a string with the IP
 *                       address.
 * @param bufsize      Size of the buffer.
 * @return             Completion status of operation: 0 (ASN_OK) = success,
 *                       negative return value is error.
 */
EXTERNRT int rtSocketAddrToStr (OSIPADDR ipAddr, char* pbuf, int bufsize);

/**
 * This function associates a local address with a socket. It is used on an
 * unconnected socket before subsequent calls to the ::rtSocketConnect or
 * ::rtSocketListen functions. See description of 'bind' socket function for
 * further details.
 *
 * @param socket       The socket's handle created by call to ::rtSocketCreate
 *                       function.
 * @param addr         The local IP address to assign to the socket.
 * @param port         The local port number to assign to the socket.
 * @return             Completion status of operation: 0 (ASN_OK) = success,
 *                       negative return value is error.
 */
EXTERNRT int rtSocketBind (OSRTSOCKET socket, OSIPADDR addr, int port);

/**
 * This function closes an existing socket.
 *
 * @param socket       The socket's handle created by call to ::rtSocketCreate
 *                       or ::rtSocketAccept function.
 * @return             Completion status of operation: 0 (ASN_OK) = success,
 *                       negative return value is error.
 */
EXTERNRT int rtSocketClose (OSRTSOCKET socket);

/**
 * This function establishes a connection to a specified socket. It is used to
 * create a connection to the specified destination. When the socket call
 * completes successfully, the socket is ready to send and receive data. See
 * description of 'connect' socket function for further details.
 *
 * @param socket       The socket's handle created by call to ::rtSocketCreate
 *                       function.
 * @param host         The null-terminated string with the IP address in the
 *                       following format: "NNN.NNN.NNN.NNN", where NNN is a
 *                       number in the range (0..255).
 * @param port         The destination port to connect.
 * @return             Completion status of operation: 0 (ASN_OK) = success,
 *                       negative return value is error.
 */
EXTERNRT int rtSocketConnect (OSRTSOCKET socket, const char* host, int port);

/**
 * This function creates a socket. The only streaming TCP/IP sockets are
 * supported at the moment.
 *
 * @param psocket      The pointer to the socket's handle variable to receive
 *                       the handle of new socket.
 * @return             Completion status of operation: 0 (ASN_OK) = success,
 *                       negative return value is error.
 */
EXTERNRT int rtSocketCreate (OSRTSOCKET* psocket);

/**
 * This function initiates use of sockets by an application. This function must
 * be called first before use sockets.
 *
 * @return             Completion status of operation: 0 (ASN_OK) = success,
 *                       negative return value is error.
 */
EXTERNRT int rtSocketsInit (void);

/**
 * This function places a socket a state where it is listening for an incoming
 * connection. To accept connections, a socket is first created with the
 * ::rtSocketCreate function and bound to a local address with the
 * ::rtSocketBind function, a maxConnection for incoming connections is
 * specified with ::rtSocketListen, and then the connections are accepted with
 * the ::rtSocketAccept function. See description of 'listen' socket function
 * for further details.
 *
 * @param socket           The socket's handle created by call to
 *                           ::rtSocketCreate function.
 * @param maxConnection    Maximum length of the queue of pending connections.
 * @return                 Completion status of operation: 0 (ASN_OK) =
 *                           success, negative return value is error.
 */
EXTERNRT int rtSocketListen (OSRTSOCKET socket, int maxConnection);

/**
 * This function receives data from a connected socket. It is used to read
 * incoming data on sockets. The socket must be connected before calling this
 * function. See description of 'recv' socket function for further details.
 *
 * @param socket       The socket's handle created by call to ::rtSocketCreate
 *                       or ::rtSocketAccept function.
 * @param pbuf         Pointer to the buffer for the incoming data.
 * @param bufsize      Length of the buffer.
 * @return             If no error occurs, returns the number of bytes
 *                       received. Otherwise, the negative value is error code.
 */
EXTERNRT int rtSocketRecv (OSRTSOCKET socket, ASN1OCTET* pbuf, ASN1UINT bufsize);

/**
 * This function sends data on a connected socket. It is used to write outgoing
 * data on a connected socket. See description of 'send' socket function for
 * further details.
 *
 * @param socket       The socket's handle created by call to ::rtSocketCreate
 *                       or ::rtSocketAccept function.
 * @param pdata        Buffer containing the data to be transmitted.
 * @param size         Length of the data in pdata.
 * @return             Completion status of operation: 0 (ASN_OK) = success,
 *                       negative return value is error.
 */
EXTERNRT int rtSocketSend (OSRTSOCKET socket, const ASN1OCTET* pdata, ASN1UINT size);

/**
 * This function converts the string with IP address to a double word
 * representation. The converted address may be used with the ::rtSocketBind
 * function.
 *
 * @param pIPAddrStr   The null-terminated string with the IP address in the
 *                       following format: "NNN.NNN.NNN.NNN", where NNN is a
 *                       number in the range (0..255).
 * @param pIPAddr      Pointer to the converted IP address.
 * @return             Completion status of operation: 0 (ASN_OK) = success,
 *                       negative return value is error.
 */
EXTERNRT int rtSocketStrToAddr (const char* pIPAddrStr, OSIPADDR* pIPAddr);

/** @} */
#ifdef __cplusplus
}
#endif

#endif /* _RTSOCKET_H_ */

