/*@(#)saprfc.h          20.60.4.1     SAP     96/06/26 */


/*
 * @doc
 *
 * @module Remote Function Call API  |
 *
 * The Remote Function Call API (RFC API) allows -
 * remotely or locally - calling ABAP/4 function
 * modules from C programs as well as receiving call
 * request issued from an ABAP/4 program by the
 * CALL FUNCTION interface.
 *
 * In ABAP/4 function modules are special routines with
 * well defined and documented interfaces, which are
 * developed within a library development workbench.
 *
 * ABAP/4 function modules use named parameter passing.
 * Also there are exceptions which can be raised by a function
 * module to indicate errors. These exceptions can be caught
 * by the caller of a function module.
 *
 * The following functions form the programming interface to
 * call ABAP/4 function modules from a C environment.
 *
 * @group Functions for a RFC client program
 * @flag <f RfcOpen>          | opens a RFC connection.
 * @flag <f RfcOpenExt>       | another way to open a RFC connection more
 *                              appropriate for non C environments as Visual Basic.
 * @flag <f RfcOpenExtV3>     | another way to open a RFC connection more
 *                              appropriate for non C environments as Visual Basic
 *                              (using RFC Version 3).
 * @flag <f RfcConnect>       | opens a RFC connection via LOAD BALANCING (R/3 only).
 * @flag <f RfcCall>          | Call an ABAP/4 function module.
 * @flag <f RfcReceive>       | Receive the return values from an
 *                              ABAP/4 function module.
 * @flag <f RfcCallReceive>   | Calling a function module and receiving the
 *                              return values in one step.
 * @flag <f RfcCreateTransID> | Get a unique Transaction-ID for calling an ABAP/4
 *                              function module using the transactional RFC Interface.
 * @flag <f RfcIndirectCall>  | Call an ABAP/4 function module using transactional RFC
 *                              Interface in R/3.
 *
 * @group Functions for a RFC server program
 * @flag <f RfcAccept>                    | accepting a RFC request or registering at a
 *                                          SAP gateway.
 * @flag <f RfcInstallFunction>           | registering functions as callable
 *                                          function modules.
 * @flag <f RfcDispatch>                  | waiting for the next function call.
 * @flag <f RfcGetData>                   | receiving the parameters of a function.
 * @flag <f RfcSendData>                  | sending back the return values.
 * @flag <f RfcRaise>                     | raising an exception.
 * @flag <f RfcGetName>                   | reading the symbolic function name.
 * @flag <f RfcCallReceive>               | Calling a function module and receiving
 *                                          the return values in one step. It can be
 *                                          be used for calling back a function module
 *                                          in R/3 using the same RFC connection while
 *                                          executing a RFC function in this server
 *                                          program. Using <f RfcCall> and <f RfcReceive>
 *                                          is also possible.
 * @flag <f RfcInstallTransactionControl> | registering functions as callable
 *                                          function modules for transactional RFC.
 *
 * @group Special Functions
 * @flag <f RfcListen>            | listen for incoming RFC events.
 * @flag <f RfcWaitForRequest>    | wait for incoming RFC requests.
 *                                  Only available after <f RfcAccept> in 
 *                                  register mode.
 *
 */

#ifndef RFC_H
#define RFC_H

#ifndef SAPRFC_H
#define SAPRFC_H

#ifdef __cplusplus
extern "C"
{
#endif

#define RFC_VERSION 3


/*
 * For Windows 3.x _WINDOWS has to be defined, as it is done
 * by MS Visual C++
 */

#ifndef SAPTYPE_H

#ifdef _WIN32
#  define SAPonNT
#endif  /* _WIN32 	*/

#ifdef _WINDOWS
#  ifndef _WIN32
#    define SAPonWINDOWS
#  endif  /* _WIN16 	*/
#endif  /* _WINDOWS     */

#endif  /* SAPTYPE_H 	*/


#if !defined(SAP_FAR)|| !defined(SAP_PASCAL)|| !defined(SAP_EXPORT)|| !defined(SAP_LOADDS) || !defined(SAP_STDCALL)
#   undef SAP_FAR
#   undef SAP_PASCAL
#   undef SAP_EXPORT
#   undef SAP_LOADDS
#   undef SAP_STDCALL
#   if defined(SAPonWINDOWS)
#       define SAP_FAR __far
#       define SAP_PASCAL __pascal
#       define SAP_EXPORT __export
#       define SAP_LOADDS __loadds
#       define SAP_STDCALL
#   elif defined(SAPonNT)
#       define SAP_FAR
#       define SAP_PASCAL
#       define SAP_EXPORT
#       define SAP_LOADDS
#       define SAP_STDCALL _stdcall
#   else
#       define SAP_FAR
#       define SAP_PASCAL
#       define SAP_EXPORT
#       define SAP_LOADDS
#       define SAP_STDCALL
#   endif
#endif

#if !defined(SAP_API)
#   if defined(OS2)
#       define _SYSTEM _System
#       define SAP_API _SYSTEM
#   else
#       define _SYSTEM
#       define SAP_API SAP_FAR SAP_LOADDS SAP_PASCAL SAP_STDCALL
#   endif
#endif /* SAP_API */

#if !defined(WIN_DLL_EXPORT_FLAGS)
#   define WIN_DLL_EXPORT_FLAGS SAP_API
#endif /* WIN_DLL_EXPORT_FLAGS */


#if !defined(DLL_CALL_BACK_FUNCTION)
#   if defined(SAPonWINDOWS)
#       define DLL_CALL_BACK_FUNCTION SAP_FAR SAP_PASCAL
#   elif defined(SAPonNT)
#       define DLL_CALL_BACK_FUNCTION SAP_STDCALL
#   elif defined(OS2)
#       define DLL_CALL_BACK_FUNCTION _SYSTEM
#   else
#       define DLL_CALL_BACK_FUNCTION		
#   endif
#   if defined(OS2)
#      define DLL_CALL_BACK_FUNCTION_PTR * _SYSTEM
#   else
#      define DLL_CALL_BACK_FUNCTION_PTR DLL_CALL_BACK_FUNCTION *
#   endif
#endif /* DLL_CALL_BACK_FUNCTION */


#if ! defined (RUNT) && ! defined (ABAP0LIB)

/* ABAP/4 data types */
#define TYPC            0
#define TYPDATE         1
#define TYPP            2
#define TYPTIME         3
#define TYPX            4
#define TYPTABH         5
#define TYPNUM          6
#define TYPFLOAT        7
#define TYPINT          8
#define TYPINT2         9
#define TYPINT1         10
#define TYP1            12
#define TYP2            13

/* internal hint :
 * ABAP/4 data types must also be defined in abtypes.h
 */

#endif /* ! defined (RUNT) && ! defined (ABAP0LIB) */

/* RFC scalar data types */

/* @type RFC_CHAR |
 * ABAP/4 data type C,
 * blank padded character string of fixed length.
 */
/* @type RFC_NUM |
 * ABAP/4 data type N,
 * character string of fixed length containing only digits.
 */
/* @type RFC_BYTE |
 * ABAP/4 data type X,
 * raw data.
 */
/* @type RFC_BCD |
 * ABAP/4 data type P,
 * packed number in BCD format (binary coded decimal).
 */
/* @type RFC_INT1 |
 * Data dictionary data type INT1,
 * 1-byte unsigned integer.
 */
/* @type RFC_INT2 |
 * Data dictionary data type INT2,
 * 2-byte signed integer.
 */
/* @type RFC_INT |
 * ABAP/4 data type I,
 * 4-byte signed integer.
 */
/* @type RFC_FLOAT |
 * ABAP/4 data type F,
 * 8-byte IEEE floating point number.
 */
/* @type RFC_DATE |
 * ABAP/4 data type D,
 * 8-byte date (YYYYMMDD).
 */
/* @type RFC_TIME |
 * ABAP/4 data type T,
 * 6-byte time (HHMMSS).
 */
typedef unsigned char  RFC_CHAR;     /* characters, TYPC	*/
typedef RFC_CHAR       RFC_NUM;      /* digits, TYPNUM  	*/
typedef unsigned char  RFC_BYTE;     /* raw data, TYPX   	*/
typedef unsigned char  RFC_BCD;      /* packed numbers, TYPP	*/
typedef unsigned char  RFC_INT1;     /* 1 byte integer, TYPINT1	*/
typedef short          RFC_INT2;     /* 2 byte integer, TYPINT2	*/
typedef double         RFC_FLOAT;    /* floating point, TYPFLOAT*/
typedef RFC_CHAR       RFC_DATE[8];  /* date, TYPDATE (YYYYMMDD)*/
typedef RFC_CHAR       RFC_TIME[6];  /* time, TYPTIME (HHMMSS)  */

/* integers */
#ifndef INT_MAX
#include<limits.h>
#endif



#define RFC_INT_MAX 0x7fffffff
#if INT_MAX == RFC_INT_MAX
 typedef int           RFC_INT;     /* 4 byte integers, TYPINT	*/
#elif LONG_MAX == RFC_INT_MAX
 typedef long int      RFC_INT;     /* 4 byte integers, TYPINT	*/
#else
#error local integer representation is not supported by RFC API
#endif



/* saptype data types */
#ifndef SAPTYPE_H
 typedef RFC_CHAR 	SAP_CHAR;
 typedef RFC_BYTE 	SAP_BYTE;
 typedef RFC_BCD  	SAP_BCD;
 typedef RFC_INT  	SAP_INT;
 typedef RFC_INT2 	SAP_SHORT;
 typedef RFC_FLOAT 	SAP_DOUBLE;
 typedef RFC_DATE 	SAP_DATE;
 typedef RFC_TIME 	SAP_TIME;
#endif

/* Initialization */
void SAP_API RfcInit( void );

/* Environment : memory allocation and error handling */

typedef void* (DLL_CALL_BACK_FUNCTION_PTR RFC_ALLOCATE)
		      ( void * old_ptr,
                        unsigned long size );
typedef void  (DLL_CALL_BACK_FUNCTION_PTR RFC_ERROR_HANDLER)
                      ( char * error_id );

typedef struct
{
   RFC_ERROR_HANDLER errorhandler;
   RFC_ALLOCATE      allocate;
}
RFC_ENV;


void SAP_API RfcEnvironment( RFC_ENV * new_env );

 /* @struct RFC_ERROR_INFO |
  * structure returned by <f RfcLastError> describing
  * the last RFC error that occurred.
  */
typedef struct
{
    char key[33];		/* @field error code to identify
                         * the error */
    char status[128];	/* @field state of the RFC
	                     * connection
						 */
    char message[256];	/* @field text describing the error */
    char intstat[128];	/* @field internal description of the
	                     * RFC connection
						 */
}
RFC_ERROR_INFO;

/*------------------------------------------------------
 * @func
 *
 * RfcLastError describes the last error reported by
 * some function of the RFC API.
 *
 * @rdesc
 * returns 1 if no error occurred and 0 elsewhere.
 *------------------------------------------------------
 */
int SAP_API RfcLastError(
  RFC_ERROR_INFO * error_info  /* @parm structure
                                * <t RFC_ERROR_INFO> describing the
                                * error.
                                */
                        );

/* @type RFC_HANDLE | handle for RFC connection
 * @flag RFC_HANDLE_NULL | the RFC handle is not set
 */
typedef unsigned RFC_HANDLE;

/* Null-Value : handle not set */
#define RFC_HANDLE_NULL   0

 /* @struct RFC_ATTRIBUTES |
  * structure returned by <f RfcGetAttributes> describing
  * some information about this RFC connection.
  */
typedef struct
{
  char dest[64+1];           /* @field RFC destination   */
  char own_host[100+1];      /* @field Own host name     */
  char partner_host[100+1];  /* @field Partner host name */
  char systnr[2+1];          /* @field R/3 system number */
  char sysid[8+1];           /* @field R/3 system name   */
  char client[3+1];          /* @field Client            */
  char user[12+1];           /* @field User              */
  char language[1+1];        /* @field Language          */
  char reserved[256];        /* @field reserved          */
}
RFC_ATTRIBUTES;

/*------------------------------------------------------
 * @func
 *
 * RfcGetAttributes returns some information about this
 * RFC connection.
 *
 * The RFC library can only know these attributes after this
 * RFC connection is established and at least one RFC function
 * is called.
 *
 * Therefore, it should be called after an <f RfcReceive>
 * in an RFC client program or after <f RfcGetData> in an
 * RFC server program.
 *
 *
 * @rdesc
 * returns 0 if no error occurred and 1 elsewhere.
 *------------------------------------------------------
 */
int SAP_API RfcGetAttributes(
  RFC_HANDLE       handle,         /* @parm connection handle. */
  RFC_ATTRIBUTES * rfc_attributes  /* @parm structure
                                * <t RFC_ATTRIBUTES> describing some
                                * information about this RFC connection.
                                */
                        );

/*
 * @enum RFC_MODE |
 *
 * Type of connection to be opened by <f RfcOpen>.
 */
typedef enum
{
  RFC_MODE_R3ONLY = 0,      /* @emem Use R/3 protocol and addressing scheme.
                             * Only for R/3 systems. Any kind
			     * of user id (dialog user id, cpic user id)
			     * is possible.
			     *
			     * <e RFC_OPTIONS.connopt> must point to a structure
			     * of type <t RFC_CONNOPT_R3ONLY>.
                             *
			     */
  RFC_MODE_CPIC = 1,        /* @emem Use R/2 protocol and addressing scheme.
                             * Must be used for R/2,
			     * cpic user id are only allowed.
                             * (Since an R/3 system is also capable of
                             * understanding the R/2 RFC protocol, you can
                             * reach also an R/3 system with that mode,
                             * you must use a 'sideinfo' file for addressing,
                             * however.
			     *
			     * <e RFC_OPTIONS.connopt> must point to a structure
			     * of type <t RFC_CONNOPT_CPIC>.
			     */
  RFC_MODE_VERSION_3 = 3,   /* @emem Use R/3 protocoll Version 3.
			     * The receiving SAP system must have at least
			     * Rel. 3.0C to be able to serve every kind
			     * of options.
			     *
			     * <e RFC_OPTIONS.connopt> must point to a structure
			     * of type <t RFC_CONNOPT_VERSION_3>.
			     */
  RFC_MODE_PARAMETER = 4    /* @emem Use R/3 protocoll Version 3 or R/2 protocol and
                             * addressing scheme.
                             * This mode includes all three modes above and all necessary
                             * parameters will be read from a INI-file (saprfc.ini).
                             * See saprfc.ini for more details
                             *
                             * In some cases the receiving SAP system must have at least
                             * Rel. 3.0C to be able to serve every kind of options.
                             *
                             * <e RFC_OPTIONS.destination> must point to a valid entry
                             * in the saprfc.ini. This file can be in the current directory
                             * where RFC programs are running or defined by the Environment
                             * Variable RFC_INI (e.g. /usr/rfctest/saprfc.ini).
                             *
			     * <e RFC_OPTIONS.connopt> must be set to NULL.
                             */
}
RFC_MODE;

/* internal use */
#define RFC_OPEN_USE_V3   '3'
#define RFC_OPEN_USE_RFC  'R'
#define RFC_OPEN_USE_CPIC ' '

/* @struct RFC_CONNOPT_CPIC |
 * Options for an SNA connection (via SAP gateway).
 * connection data must be specified at the SAP gateway,
 * 'destination' is used as key into the 'sideinfo' file there.
 */
typedef struct
{
   char *   gateway_host;       /* @field gateway hostname
                                 */
   char *   gateway_service;    /* @field gateway service
                                 * (in general sapgw00).
                                 */
}
RFC_CONNOPT_CPIC;


/* @struct RFC_CONNOPT_R3ONLY |
 * Options for a connection to an R/3 system.
 */
typedef struct
{
   char *   hostname;           /* @field Host name of target system.
                                 * Host names can be regular host
                                 * names
                                 * defined in a 'hosts' file,
                                 * an IP address like
                                 * 123.123.123.123 or a saprouter
                                 * address as
                                 * /H/hostname/S/port/H/host/S/port/...
				 */
   int      sysnr;              /* @field system number (0-99).
                                 * This is the number by which
                                 * the target system
                                 * is identified. In general this is 0.
				 */
   char *   gateway_host;       /* @field gateway hostname.
				 * If the pointer is NULL, the gateway is
				 * assumed to run at 'hostname'.
				 */
   char *   gateway_service;    /* @field gateway service.
				 * If the pointer is NULL,
				 * the service "sapgw##" with
				 * ## = 'sysnr' is assumed.
				 */
}
RFC_CONNOPT_R3ONLY;


/* @struct RFC_CONNOPT_VERSION_3 |
 * Options for a connection to a R/3 system.
 * The target system must be of release 3.0C or later.
 *
 * Since a R/3 system of version 3.0 always has it's
 * own 'gateway' process, no gateway options are necessary
 * any more.
 */
typedef struct
{
   char *   hostname;           /* @field Host name of target system.
                                 * Host names can be regular host
                                 * names
                                 * defined in a 'hosts' file,
                                 * an IP address like
                                 * 123.123.123.123 or a saprouter
                                 * address as
                                 * /H/hostname/S/port/H/host/S/port/...
                                 *
				 * If 'use_load_balancing' is set to a non-zero
				 * value, this field can be NULL.
				 *
				 */
   RFC_INT  sysnr;              /* @field system number (0-99).
                                 * This is the number by which
                                 * the target system
                                 * is identified. In general this is 0.
				 *
				 * If 'use_load_balancing' is set to a non-zero
				 * value, this field is ignored.
				 *
				 */
   RFC_INT use_load_balancing;  /* @field Use the load balancing features
				 * of a SAP system.
				 *
				 * If you set this to a non-zero value,
				 * 'hostname' and 'sysnr' are ignored.
				 *
				 * You must set the fields 'lb_host'
				 * and 'lb_system_name' instead.
				 *
				 * The target system is determined dynamically
				 * then.
				 *
				 */
   char *  lb_host;             /* @field Host name where the 'message server'
				 * of the target system is running.
				 *
				 * This field must only be filled, if
				 * 'use_load_balancing' is set to a non-zero
				 * value.
				 */
   char *  lb_system_name;      /* @field Name of the target system (C11 i.e.)
				 *
				 * This field must only be filled, if
				 * 'use_load_balancing' is set to a non-zero
				 * value.
				 */
   char *  lb_group;            /* @field application server group.
				 *
				 * The group of application servers to be used.
				 *
				 * This field must only be filled, if
				 * 'use_load_balancing' is set to a non-zero
				 * value.
				 */
   RFC_INT use_sapgui;          /* @field use 'sapgui' process to
				 * display SAP dynpros and graphics.
				 *
				 * Set this to a non-zero value to activate
				 * this functionality.
				 *
				 * Starting sapgui takes some time, so
				 * you should not set that value, if you do not
				 * need it.
				 *
				 * This field is set implicitly as soon as
				 * you activate the ABAP/4 debugger by
				 * entering 'D' in the <e RFC_OPTIONS.trace> field or
				 * by setting RFC_DEBUG in the system environment.
				 *
				 */
    double reserve[4];
}
RFC_CONNOPT_VERSION_3;


/* @struct RFC_OPTIONS |
 * parameters for <f RfcOpen>.
 *
 * Depending on the type of connection various data have to be supplied
 * to open a RFC connection.
 *
 * There are 3 ways to supply this information:
 *
 * 1. You can enter a destination name pointed to an entry in a 'saprfc.ini'
 *    file which contains the necessary network parameters and RFC specific
 *    parameters for opening the connection at <f RfcOpen>.
 *
 * 2. You can enter a destination name pointed to an entry in a 'sideinfo'
 *    file which only contains the necessary network parameters for opening
 *    the connection at <f RfcOpen>.
 *
 * 3. You supply in your program all the data needed for opening the
 *    connection at <f RfcOpen>.
 *
 *
 *
 * We recommend the first one (working with saprfc.ini) because you can use some
 * RFC features today and in the future without changes in your RFC programs.
 *
 * See saprfc.ini for more details.
 *
 *
 *
 * Fields that are not supplied must be set to NULL.
 *
 * The structure consists of 3 groups.
 *
 * The data needed to establish the physical connection depend on
 * the type of connection (R/2 or R/3 connection, version , ... ).
 * Depending on the contents of the field 'mode', the field 'connopt'
 * must point to different structures.
 *
 * The sign on data ( client, user, password, language ) are needed
 * for authentication. Since <f RfcOpen> only opens the physical connection
 * directly. these data are only checked if the first RFC call is
 * send.
 *
 * The third field contains a trace flag. If not zero, a trace file
 * is written for all the operations corresponding to this connection
 * to ease error analysis.
 *
 * Please make sure, that this structure is completely initialized
 * with 0 to allow adding more connection parameters in the future
 * by SAP.
 *
 * @ex Options for a R/3 connection. |
 *
 * // static = initialized structures
 * static RFC_OPTIONS        options;
 * static RFC_CONNOPT_R3ONLY rfc_connopt_r3only;
 * RFC_HANDLE                handle;
 *
 * options.destination = "TEST";
 * options.mode        = RFC_MODE_R3ONLY;
 * options.client      = "000";
 * options.user        = "SAP*";
 * options.language    = "E";
 * options.password    = "PASS";
 * options.trace       = 0;                    // turn trace off
 *
 * options.connopt     = &rfc_connopt_r3only;
 *
 * rfc_connopt_r3only.hostname = "some_host";  // some host name
 * rfc_connopt_r3only.sysnr    = 0;            // system 00
 *
 * handle = RfcOpen( &options );
 * if ( handle == RFC_HANDLE_NULL )
 * {
 *    .....
 *
 */
typedef struct
{
   char *   destination;        /* @field name of destination.
                                 * If the connection is not described
                                 * completely, this name is used as a
                                 * key for a 'sideinfo', where the
                                 * connection should be described then.
                                 * You always have to fill this field.
                                 */

   /* connection data */
   RFC_MODE mode;               /* @field connection mode.
                                 * There are two different protocol
                                 * types for RFC, depending on whether
                                 * your target system is a R/2 or a R/3
                                 * system.
				 *
				 * If your target system is a SAP system
				 * of Release 3.0C or later you can use
				 * variuos special options, if you enter
				 * the value <e RFC_MODE.RFC_MODE_VERSION_3>
				 * here.
				 *
				 * Depending on the content of
                                 * this field, connopt must point to
                                 * different structures.
                                 * (s. <t RFC_MODE>).
				 */
   void *   connopt;            /* @field If connopt is NULL, the 'sideinfo'
				 * or the 'saprfc.ini' file is used to determine the
				 * the connection parameters.
				 *
				 * Without 'sideinfo' file
				 * 'connopt' must point to a structure
				 * of type <t RFC_CONNOPT_R3ONLY>,
				 * <t RFC_CONNOPT_VERSION_3> or
				 * <t RFC_CONNOPT_CPIC> depending
				 * on the value of 'mode'.
                                 *
				 */

   /* sign on data */
   char *   client;             /* @field signon data: client   */
   char *   user;               /* @field signon data: user id  */
   char *   password;           /* @field signon data: password */
   char *   language;           /* @field signon data: language */

   /* options */
   int      trace;              /* @field trace.
                                 * If 0, no trace is written,
                                 * if not 0, the RFC library traces
                                 * all activities into a file 'dev_rfc'
                                 * in the actual working directory.
				 *
				 * If your target system is of release 3.0C
				 * or later, you can enter the value 'D' here
				 * to start the ABAP/4 debugger on the target
				 * system.
				 *
				 * The ABAP/4 debugger can also be activated
				 * by setting the environment variable
				 * RFC_DEBUG before the call to <f RfcOpen>
				 * is done.
                                 */
}
RFC_OPTIONS;


#define RFC_HOSTNAME_LN        100
typedef char RFC_HOSTNAME[RFC_HOSTNAME_LN+1];


/* @func
 * opens a RFC connection via LOAD BALANCING
 * (only available for R/3 Release 3.0 onwards).

 * With this function the RFC library will try to connect to an
 * application server with the least load (LOAD BALANCING principle)
 * within a group of predefined application servers.
 *
 * This function has following advantages:
 *
 * 1. The load in R/3 system is distributed to different application server
 *
 * 2. RFC connections are thus independent of a specific application server.
 *    (With <f RfcOpen> or <f RfcOpenExt> a RFC connection could only be established
 *    to a predefined application server).
 *
 * 3. Only the host name of the message server and its port number of the
 *    according R/3 are required in the host file and the services file.
 *
 *    Information about SAP gateway, application server, system number,... as
 *    parameter for <f RfcOpen>, <f RfcOpenExt> or as parameter in sideinfo are no longer
 *    necessary. Even the sideinfo is no longer required.
 *
 *
 *
 * ATTENTION:
 *
 * Please use <f RfcOpen> or <f RfcOpenExtV3> with <t RFC_MODE> RFC_MODE_VERSION_3
 * or RFC_MODE_PARAMETER instead of this function.
 *
 *
 * @rdesc
 * returns a handle to the RFC connection (<t RFC_HANDLE>) or
 * RFC_HANDLE_NULL, if the connection cannot be opened.
 *
 * @xref <f RfcOpen> <t RFC_OPTIONS> <f RfcOpenExtV3> <t RFC_OPTIONS>
 */
RFC_HANDLE SAP_API RfcConnect(
char *       system_name, /* @parm name of the R/3 system */
char *       ms_hostname, /* @parm hostname of the message server */
char *       group_name,  /* @parm name of a specific group of application servers */
char *       client,      /* @parm signon data: client */
char *       user,        /* @parm signon data: user id */
char *       password,    /* @parm signon data: password */
char *       language,    /* @parm signon data: language */
int          trace,       /* @parm trace ( 0 / 1 ). */
RFC_HOSTNAME as_hostname, /* @parm name of the connected App. Server (Output parm.) */
int  *       sysnr);      /* @parm system number of the connected R/3 system (Output parm.) */

/* @func
 * opens a RFC connection.
 * all parameters are passed as single fields.
 *
 * @rdesc
 * returns a handle to the RFC connection (<t RFC_HANDLE>) or
 * RFC_HANDLE_NULL.
 *
 * @xref <f RfcOpen> <f RfcOpenExtV3> <t RFC_OPTIONS>
 */
RFC_HANDLE SAP_API RfcOpenExt (
char*    destination,  /* @parm name of destination. */
RFC_MODE mode,         /* @parm connection mode ( <t RFC_MODE> ). */
char*    hostname,     /* @parm hostname of target system. */
int      sysnr,        /* @parm system number ( 0 - 99 ). */
char*    gateway_host, /* @parm gateway hostname or NULL */
char*    gateway_service,  /* @parm gateway service or NULL */
char*    client,           /* @parm signon data: client */
char*    user,             /* @parm signon data: user id */
char*    password,         /* @parm signon data: password */
char*    language,         /* @parm signon data: language */
int      trace);           /* @parm trace ( 0 / 1 ). */

/* @func
 * opens a RFC connection.
 * all parameters are passed as single fields.
 * (using the all possible <t RFC_MODE>)
 *
 * Following parameters in this call are always needed:
 *   <t RFC_MODE> mode,
 *   SAP-logon-Info: client, user, password, language
 *   trace
 *   use_sapgui
 *
 * Depending of <t RFC_MODE> mode following parameters are necessary:
 *
 * RFC_MODE_CPIC:
 *
 *   - destination must be defined.
 *
 *   - gateway_host and gateway_service can be defined.
 *
 *   - sideinfo is necessary.
 *
 * RFC_MODE_R3ONLY/RFC_MODE_VERSION_3:
 *
 *   - use_load_balancing is 0 (OFF)
 *
 *       destination is not NULL:
 *
 *         gateway_host, gateway_service, hostname and sysnr
 *         can be defined. sideinfo is necessary.
 *
 *       destination is NULL:
 *
 *         gateway_host and gateway_service can be defined.
 *         hostname, sysnr must be defined.
 *
 *   - use_load_balancing is 1 (ON):
 *
 *       destination, gateway_host, gateway_service,
 *       hostname and sysnr will not be evaluated.
 *
 *       lb_host and lb_system_name must be defined.
 *       if lb_group is NULL the group 'PUBLIC' will be used.
 *
 *
 * ATTENTION:
 *
 *   - use_sapgui and ABAP-Debug are only available with R/3 3.0C or later
 *     and not on Windows with 16-bit-RFC-library.
 *
 *   - use_sapgui and ABAP-Debug are not available with R/2.
 *
 *
 * @rdesc
 * returns a handle to the RFC connection (<t RFC_HANDLE>) or
 * RFC_HANDLE_NULL.
 *
 * @xref <f RfcOpen>  <f RfcOpenExtV3> <t RFC_OPTIONS>
 */
RFC_HANDLE SAP_API RfcOpenExtV3 (
char*    destination,  /* @parm name of destination or NULL */
RFC_MODE mode,         /* @parm connection mode ( <t RFC_MODE> ) */
char*    hostname,     /* @parm hostname of target system or NULL */
int      sysnr,        /* @parm system number ( 0 - 99 ) */
char*    gateway_host, /* @parm gateway hostname or NULL */
char*    gateway_service,  /* @parm gateway service or NULL */
char*    client,           /* @parm signon data: client */
char*    user,             /* @parm signon data: user id */
char*    password,         /* @parm signon data: password */
char*    language,         /* @parm signon data: language */
int      trace,            /* @parm trace (OFF/ON/ABAP-DEBUG: 0/1/2) */
RFC_INT  use_load_balancing, /* @parm using load balancing feature (OFF/ON: 0/1)*/
char*    lb_host,          /* @parm Host name of the 'message server' */
char*    lb_system_name,   /* @parm Name of the target system (C11 i.e.) */
char*    lb_group,         /* @parm application server group or NULL for PUBLIC */
RFC_INT  use_sapgui        /* @parm using sapgui to display SAP dynpros and graphics (OFF/ON: 0/1)*/
);

/* @func
 * opens a connection according to the given options.
 * The structure <t RFC_OPTIONS>
 * contains the necessary data for opening the connection
 * @rdesc
 * returns a handle to the RFC connection (<t RFC_HANDLE>) or
 * RFC_HANDLE_NULL, if the connection cannot be opened.
 *
 * @xref <f RfcOpenExt> <f RfcOpenExtV3>
 */
RFC_HANDLE SAP_API RfcOpen(
  RFC_OPTIONS * options  /* @parm connection parameters as described
                          * at structure <t RFC_OPTIONS>.
                          */
                          );
/*--------------------------------------------------------------
 * @func
 * accepts an incoming connection and has to be used, if the program
 * was started by a RFC call issued by a SAP system or an other
 * program using this API. The command line (argv) has to be passed
 * to this function.
 *
 * With Release 3.0C onwards this function can be used to register at
 * a SAP gateway and the server program can wait for next RFC request
 * by issueing <f RfcDispatch> or <f RfcWaitForRequest> or <f RfcListen>
 * or <f RfcGetName>.
 *
 * Using this functionality a RFC server program can now already run
 * and work as a RFC daemon. A start of any server program by a R/3
 * application server, by SAPGUI or via remote shell by a SAP gateway
 * is no longer necessary.
 *
 * There are 2 ways to define the input parameter 'argv': 
 *
 * 1. Working with 'saprfc.ini'-file:
 *
 *    -D<lt>destination pointed to an entry in 'saprfc.ini'<gt>
 *
 *    -t      Set RFC-Trace on
 *
 *
 * 2. Working without 'saprfc.ini'-file:
 *
 *    -a<lt>program ID<gt> e.g. own_host_name.program_name
 *
 *    -g<lt>host name of the SAP gateway<gt>
 *
 *    -s<lt>service of the SAP gateway<gt>, e.g. sapgw00
 *
 *    -t      Set RFC-Trace on
 *
 *
 *
 * We recommend the first one because you can use some RFC features today
 * and in the future without changes in your RFC programs.
 *
 * See saprfc.ini for more details.
 *
 *
 *
 * The 3 parameters above must fit with the configuration in R/3.
 * (via SM59, Connection type T and Register Mode)
 *
 * For working with register mode there are no other changes in RFC
 * server programs necessary.
 *
 * Be carefull by using only the program name as program ID because
 * there might be more programs (e.g. rfcexec) registered at the
 * same SAP gateway. Please use at least the host name of the computer where
 * your RFC server program is running as a part of the program ID.
 *
 * Example: The well-known rfcexec program can be started from the
 *          command line with RFC-trace as follows:
 *
 *          rfcexec -ap10234.rfcexec -ghs0311 -xsapgw53 -t
 *
 *       or
 *
 *          rfcexec -Drfctest
 *
 *          and an entry in saprfc.ini can be defined as follows:
 *
 *          DEST=rfctest
 *
 *          TYPE=R
 *
 *          PROGID=p10234.rfcexec
 *
 *          GWHOST=hs0311
 *
 *          GWSERV=sapgw53
 *
 *          RFC_TRACE = 1
 *
 *
 *
 * RFC server programs working with this functionality will be called
 * RFC server programs running in register mode.
 *
 * @rdesc
 * returns a valid <t RFC_HANDLE> or RFC_HANDLE_NULL
 *--------------------------------------------------------------
 */
RFC_HANDLE SAP_API RfcAccept(
  char ** argv /* @parm command line (argv),
                * the program is started with.
                */
  );

RFC_HANDLE SAP_API RfcAcceptExt( char* CommandLine );

/*----------------------------------------------------------------------------
@func

closes a RFC connection.

----------------------------------------------------------------------------*/
void       SAP_API RfcClose(
  RFC_HANDLE handle   /* @parm handle to RFC connection */
                           );

/*----------------------------------------------------------------------------
@func

sends a error message, if possible, and closes the connection.

A given error message cannot be send, if the receiver is not in state,
where it expects some RFC data to receive.
----------------------------------------------------------------------------*/
void       SAP_API RfcAbort(
  RFC_HANDLE handle,  /* @parm handle to RFC connection */
  char * text         /* @parm error message.
                       *
                       * If this field is NULL, the connection is
                       * only closed.
                       */
  );

/* @enum RFC_RC | RFC return codes */
typedef enum
{
   RFC_OK,                /* @emem O.K.
			   */
   RFC_FAILURE,           /* @emem Error occurred
			   */
   RFC_EXCEPTION,         /* @emem Exception raised
			   */
   RFC_SYS_EXCEPTION,     /* @emem System exception raised, connection closed
			   */
   RFC_CALL,              /* @emem Call received
			   */
   RFC_INTERNAL_COM,      /* @emem Internal communication, repeat (internal use only)
			   */
   RFC_CLOSED,            /* @emem Connection closed by the other side
			   */
   RFC_RETRY,             /* @emem No data yet (RfcListen or RfcWaitForRequest only)
			   */
   RFC_NO_TID,            /* @emem No Transaction ID available
			   */
   RFC_EXECUTED,          /* @emem Function already executed
			   */
   RFC_SYNCHRONIZE,        /* @emem Synchronous Call in Progress (only for Windows)
			   */
   RFC_MEMORY_INSUFFICIENT,/* @emem Memory insufficient
			   */
   RFC_VERSION_MISMATCH,   /* @emem Version mismatch
			   */
   RFC_NOT_FOUND,          /* @emem Function not found (internal use only)
			   */
   RFC_CALL_NOT_SUPPORTED  /* @emem This call is not supported on WINDOWS
			   */
}
RFC_RC;

/* @struct RFC_PARAMETER |
 * RFC parameters.
 *
 * Describes 'Exporting' and 'Importing' parameters of the
 * interface of a function module.
 *
 * @xref <t RFC_CHAR>, <t RFC_NUM>, <t RFC_BYTE>, <t RFC_BCD>,
 *       <t RFC_INT1>, <t RFC_INT2>, <t RFC_INT>, <t RFC_FLOAT>,
 *       <t RFC_DATE>, <t RFC_TIME>.
 */
typedef struct
{
   void *   name;  /* @field Name of the field (in the interface
		    * definition of the function).
		    */
   unsigned nlen;  /* @field Length of the name
		    * (should be strlen(name)).
		    */
   unsigned type;  /* @field Data type of the field.
		    */
   unsigned leng;  /* @field Length of the field in Bytes.
		    */
   void *   addr;  /* @field Address of the field to be exported
		    * or imported.
		    */
}
RFC_PARAMETER;


#ifndef SAPITAB_H
typedef void * ITAB_H;
#endif

/* @enum RFC_ITMODE | mode how to pass internal table */
typedef enum
{
   RFC_ITMODE_BYREFERENCE,  /* @emem Table is passed by reference
			     * (ALLWAYS USE THIS)
			     */
   RFC_ITMODE_BYVALUE,      /* @emem Table is passed by value, changes
			     * are not transported back
			     * (internal use only !)
			     */
   RFC_ITMODE_KEEPALIVE     /* @emem Table is passed by reference, but
			     * is kept alive after returning,
			     * (i.e. after RfcSendData, internal use
			     * only )
			     */
}
RFC_ITMODE;

/* @struct RFC_TABLE |
 * RFC tables.
 *
 * Describes Tables parameters of the interface of a function module.
 */
typedef struct
{
   void *   name;      /* @field Name of the table (in the interface
			* definition of the function).
			*/
   unsigned nlen;      /* @field Length of the name
			* (should be strlen(name)).
			*/
   unsigned type;      /* @field Data type of the lines of the table.
			*/
   unsigned leng;      /* @field length of a row in bytes.
			*/
   ITAB_H   ithandle;  /* @field Table handle <t ITAB_H>,
			* i.e. the address of
			* the control structure of the
			* internal table.
			*
			* This is an input field at <f RfcCall> and
			* an output field at <f RfcGetData>.
			*/
   RFC_ITMODE itmode;  /* @field mode ( <t RFC_ITMODE> ),
                        * how this table has to be received :
			* 'call by reference' or 'call by value'.
			* (only for RfcGetData, has no effect
			*  in RfcCall).
			*/
   int      newitab;   /* @field If the value is not 0 after RfcGetData,
                        * the table was created by RfcGetData.
			* Internal use only. This field must not
			* be modified
			* between <f RfcGetData> and <f RfcSendData> !
			*/
}
RFC_TABLE;

/* -------------------------------------------------------------------
 * security and automatic (re)connection
 * ------------------------------------------------------------------*/

typedef RFC_BYTE RFC_TICKET_CHECKSUM[20];   /* SHA checksum */
typedef RFC_BYTE RFC_TICKET_SYSNAME[8];

typedef struct
{
                         		/* position	*/
   RFC_BYTE   	head	[4];    	/* 0-4 		*/
   RFC_BYTE     unused	[8];    	/* 4-12		*/
   RFC_BYTE   	ip	[4];		/* 12-16	*/
   RFC_BYTE	sysnr	[1];		/* 16-17	*/
   RFC_BYTE	client	[3];		/* 17-20	*/
   RFC_TICKET_SYSNAME   sysname;	/* 20-28	*/
   RFC_BYTE	userid	[14];		/* 28-42	*/
   RFC_BYTE	valid	[2];		/* 42-44	*/
   RFC_TICKET_CHECKSUM	check;   	/* 44-64	*/
                                        /* size 64   	*/
}
RFC_TICKET;

/* for internal use only */
#define NEWITAB_SHARE   0
#define NEWITAB_POP     1
#define NEWITAB_KEEP    2
#define NEWITAB_BYVALUE 3
#define NEWITAB_COPY    4


/* @type RFC_FUNCTIONNAME | RFC function name.
 * Character field big enough containing the name of any
 * ABAP/4 function module.
 */
#define RFC_FUNCTIONNAME_LN   31
typedef char RFC_FUNCTIONNAME[RFC_FUNCTIONNAME_LN];

/* RFC Transaction Identifier (TID) */
#define RFC_TID_LN            24        /* Offsetof (ARFCSDATA, arfcdest)    */
#define RFC_CALLID_LN         64        /* Offsetof (ARFCSDATA, arfcblcnt)   */
#define ARFCSDATA_HEADER_LN   68        /* Offsetof (ARFCSDATA, arfcdata01)  */

/* @type RFC_TID |
 * null terminated string giving  an RFC transaction a globally unique
 * identifier.
 */
typedef char RFC_TID[RFC_TID_LN+1];


/* ------------------------------------------------------------------
 * Standard RFC interface
 * ----------------------------------------------------------------*/


/* -----------------------------------------
 * calling function modules
 * ---------------------------------------*/

/* @func
 * Calls an ABAP/4 function module via RFC.
 *
 * The structures <t RFC_PARAMETER> and  <t RFC_TABLE> contain
 * name and description of the 'exporting' parameters and tables
 * (internal ABAP/4 table) of the function's interface.
 * The function returns after the call request is send.
 * If the function returns RFC_OK, there is no guaranty, that
 * the call was already received by the target system.
 *
 * @rdesc
 * returns RFC_OK or RFC_FAILURE.
 *
 * @ex calling the function module  RFC_SYSTEM_INFO. |
 *
 *   RFC_RC             rfc_rc;
 *   RFC_PARAMETER      exporting[32];
 *   RFC_TABLE          tables[32];
 *
 *   exporting[0].name = NULL;
 *   tables[0].name    = NULL;
 *
 *   rfc_rc = RfcCall( handle, "RFC_SYSTEM_INFO",
 *				    exporting,
 *				    tables );
 *   if( rfc_rc != RFC_OK )
 *   {
 *      ....
 *
 */
RFC_RC SAP_API RfcCall(
 RFC_HANDLE       handle,    /* @parm connection handle.
                              */
 char *           function,  /* @parm function module to call.
                              */
 RFC_PARAMETER *  parameters,/* @parm 'exporting' parameters.
                              */
 RFC_TABLE     *  tables     /* @parm 'tables' parameters.
                              */
                      );

/*----------------------------------------------------------------------
 * @func
 * receives the return values from a function call issued by <f RfcCall>.
 *
 * allows to receive the answer to a RFC call and must be called
 * after RfcCall was issued. The tables' description ( <t RFC_TABLE> )
 * must be identical to the one used in RfcCall.
 *
 * The function RfcReceive waits till the answer is received.
 *
 * @rdesc
 * returns
 * @flag <e RFC_RC.RFC_OK>  |
 *       The call was successfully completed and
 *       the values of the returned parameters were filled into the
 *       fields being supplied by the <t RFC_PARAMETER> array.
 * @flag <e RFC_RC.RFC_FAILURE> |
 *       An internal error has occurred.
 *       <f RfcLastError> may give more information.
 * @flag <e RFC_RC.RFC_EXCEPTION> |
 *       The callee has raised an exception.
 *       The field '*exception' points to the name of the exception. No
 *       data were transported.
 * @flag <e RFC_RC.RFC_SYS_EXCEPTION> |
 *       The local or remote RFC system has
 *       raised an exception. Also '*exception' points to the name of
 *       the exception. The connection was automatically closed by the
 *       system and <f RfcLastError> may give more information on the origin
 *       of the error. Two exceptions may occur now: SYSTEM_FAILURE and
 *       COMMUNICATION_FAILURE.
 * @flag <e RFC_RC.RFC_CALL>  |
 *       The callee has issued a RFC call to the
 *       caller of RfcReceive. No data are transported. The call request
 *       must be handled by using the functions <f RfcDispatch> or by
 *       <f RfcGetName>, <f RfcGetData> and <f RfcSendData>
 *       before another call to RfcReceive can be done.
 *
 * @xref <f RfcCall> <f RfcCallReceive>.
 */
  RFC_RC SAP_API RfcReceive(
  RFC_HANDLE    handle,      /* @parm connection handle.
                              */
  RFC_PARAMETER *  parameters,/* @parm 'importing' parameters.
                               */
  RFC_TABLE     *  tables,   /* @parm 'tables' parameters.
                              */
  char **          exception /* @parm output parameter:
                              * pointer to exception string.
                              * only set, if <e RFC_RC.RFC_EXCEPTION> or
                              * <e RFC_RC.RFC_SYS_EXCEPTION> is returned.
                              */
 );


/* @func
 * calls an ABAP/4 function module and receives the return values
 * in one function call.
 * @rdesc
 * returns
 * @flag <e RFC_RC.RFC_OK>  |
 *       The call was successfully completed and
 *       the values of the returned parameters were filled into the
 *       fields being supplied by the <t RFC_PARAMETER> array.
 * @flag <e RFC_RC.RFC_FAILURE> |
 *       An internal error has occurred.
 *       <f RfcLastError> may give more information.
 * @flag <e RFC_RC.RFC_EXCEPTION> |
 *       The callee has raised an exception.
 *       The field '*exception' points to the name of the exception. No
 *       data were transported.
 * @flag <e RFC_RC.RFC_SYS_EXCEPTION> |
 *       The local or remote RFC system has
 *       raised an exception. Also '*exception' points to the name of
 *       the exception. The connection was automatically closed by the
 *       system and <f RfcLastError> may give more information on the origin
 *       of the error. Two exceptions may occur now: SYSTEM_FAILURE and
 *       COMMUNICATION_FAILURE.
 * @flag <e RFC_RC.RFC_CALL>  |
 *       The callee has issued an RFC call to the
 *       caller of RfcReceive. No data are transported. The call request
 *       must be handled by using the functions <f RfcDispatch> or by
 *       <f RfcGetName>, <f RfcGetData> and <f RfcSendData>
 *       before an other call to RfcReceive can be done.
 *
 * @xref <f RfcCall> <f RfcReceive>.
 */
RFC_RC SAP_API RfcCallReceive(
 RFC_HANDLE       handle,    /* @parm connection handle.
                              */
 char *           function,  /* @parm function module to call.
                              */
 RFC_PARAMETER *  exporting, /* @parm 'exporting' parameters.
                              */
 RFC_PARAMETER *  importing,/* @parm 'importing' parameters.
                              */
 RFC_TABLE     *  tables,   /* @parm 'tables' parameters.
                             */
 char **          exception /* @parm output parameter:
                             * pointer to exception string.
                             * only set, if <e RFC_RC.RFC_EXCEPTION> or
                             * <e RFC_RC.RFC_SYS_EXCEPTION> is returned.
                             */
 );

/* @func
 *
 * call a function module in R/3 indirectly.
 *
 * With this function the call of a function module in R/3 will use the
 * transactional RFC interface in R/3.
 *
 * Importing parameters are not supported.
 *
 * If an error occurs (almost communication error) the RFC client program
 * has to reconnect to R/3 later and repeat this RFC call with the specific
 * TransID. It must NOT create a new TransID via <f RfcCreateTransID>.
 *
 * If the RFC client program takes care of the TID management and repeats
 * this RFC call in error cases the function module will be executed
 * exactly once in R/3.
 *
 * @xref <f RfcCreateTransID>, <t RFC_TID>
*/
RFC_RC SAP_API RfcIndirectCall(
 RFC_HANDLE       handle,    /* @parm connection handle. */
 char *           function,  /* @parm function module to call. */
 RFC_PARAMETER *  exporting, /* @parm 'exporting' parameters. */
 RFC_TABLE     *  tables,    /* @parm 'tables' parameters. */
 RFC_TID          tid        /* @parm according Transaction-ID. */
 );


/* ---------------------------------------------
 * Receiving an RFC function call
 * -------------------------------------------*/

/* Reading the function name */

/*----------------------------------------------------------------------
@func
Besides using <f RfcDispatch> it is also possible
to receive RFC call directly. The function
RfcGetName must then be used to get the name of the called function.
The calling program then has to determine the interface of the
requested function module and to receive the parameters as within
a function being installed via <f RfcInstallFunction>.

In register mode (s. <f RfcAccept>) the server program will wait for
the next RFC requests.

@rdesc
<e RFC_RC.RFC_OK> or <e RFC_RC.RFC_FAILURE>.

@xref <f RfcDispatch>, <f RfcInstallFunction>, <f RfcGetData>,
      <f RfcSendData>
---------------------------------------------------------------------*/
RFC_RC SAP_API RfcGetName (
  RFC_HANDLE   handle,           /* @parm RFC connection handle */
  RFC_FUNCTIONNAME functionname  /* @parm output parameter,
                                  * name of the called function module
                                  * ( <t RFC_FUNCTIONNAME> ).
                                  */
                          );

/* reading the import parameters */

/*---------------------------------------------------------------------
@func

Within a function registered via <f RfcInstallFunction>
or after receiving the name of the
called function by <f RfcGetName>  the function RfcGetData can be
used to receive the parameters of the function call.

Here the <t ITAB_H> field in the <t RFC_TABLE> record has to be
initialized to NULL. The function RfcGetData fills in the
corresponding table handle, which is either a newly created table
or an already existing table, which was send to the caller via
another RFC call.  The field itmode in an <t RFC_TABLE> record
determines if a received table is passed by reference or by
value.

@rdesc
<e RFC_RC.RFC_OK> or <e RFC_RC.RFC_FAILURE>.
---------------------------------------------------------------------*/
RFC_RC SAP_API RfcGetData (
  RFC_HANDLE   handle,          /* @parm RFC connection handle */
  RFC_PARAMETER *  parameters,  /* @parm 'importing' parameters
                                 * ( <t RFC_PARAMETER> ).
                                 */
  RFC_TABLE     *  tables );    /* @parm 'tables' parameters
                                 * ( <t RFC_TABLE> ).
                                 */


/* sending back the output parameters */



/*------------------------------------------------------------------------
@func
This function is used to send back the answer of a Remote Function Call
to a caller .

The tables description ( <t RFC_TABLE> ) must be the same than in the
previous RfcGetData call.

@rdesc
<e RFC_RC.RFC_OK> or <e RFC_RC.RFC_FAILURE>.
------------------------------------------------------------------------*/
RFC_RC SAP_API RfcSendData(
  RFC_HANDLE   handle,        /* @parm RFC connection handle */
  RFC_PARAMETER *  parameters, /* @parm 'exporting' parameters
                                */
  RFC_TABLE     *  tables );   /* @parm 'tables' parameters.
                                * Must be the same structure as passed to
                                * <f RfcGetData>.
                                */

/* raise an exception */
/*------------------------------------------------------------------------
@func
This function is used to raise an exception while processing a
Remote Function Call.

If you are having tables parameters in your function module, use
<f RfcRaiseTables> instead.

@rdesc
<e RFC_RC.RFC_OK> or <e RFC_RC.RFC_FAILURE>.

@xref
<f RfcRaiseTables>
------------------------------------------------------------------------*/
RFC_RC SAP_API RfcRaise(
 RFC_HANDLE      handle,     /* @parm RFC connection handle */
 char *           exception  /* @parm exception to be raised
                              * (null terminated string).
                              */
                       );
/* raise an exception (with tables parameters) */
/*------------------------------------------------------------------------
@func
This function is used to raise an exception while processing a
Remote Function Call, if the function module being called has
tables parameters.

@rdesc
<e RFC_RC.RFC_OK> or <e RFC_RC.RFC_FAILURE>.

@xref
<f RfcRaise>
------------------------------------------------------------------------*/
RFC_RC SAP_API RfcRaiseTables(
 RFC_HANDLE      handle,     /* @parm RFC connection handle */
 char *           exception, /* @parm exception to be raised
                              * (null terminated string).
                              */
 RFC_TABLE *      tables     /* @parm tables parameters as received by
                              * <f RfcGetData>.
			      */
                       );



/* --------------------------------------------
 * Waiting
 * ------------------------------------------*/

/*-----------------------------------------------------------------------------
@func

can be used to check if there is a RFC request available.

If one does not always want to wait for the answer to an RFC call
by <f RfcReceive>  one has to call the function RfcListen
to listen for incoming RFC events.

The function always returns immediately.
If RfcListen returns <e RFC_RC.RFC_OK>, RfcReceive has to be called to
handle the event. It only is possible  to listen for one incoming
RFC message at a time.

It is also possible to use RfcListen while waiting for a new RFC request
by <f RfcDispatch> with or without register mode (s. <f RfcAccept>). Because
RfcListen will immediately return, it is recommended to use <f RfcWaitForRequest>
to wait for new RFC requests.

@rdesc
The function returns  <e RFC_RC.RFC_OK>,
if there is an RFC event pending (call or return) and  <e RFC_RC.RFC_RETRY>,
if nothing has arrived yet. The function returns <e RFC_RC.RFC_FAILURE>, if
an error has occurred .

@ex Using RfcListen while waiting for the answer of a remote function call. |

RFC_RC rc;

rc = RfcCall( handle, .... );

do
{
   rc = RfcListen( handle );
   if( rc == RFC_RETRY )
   {
      // while waiting for the RFC answer, do something...
      ...
   }
} while ( rc == RFC_RETRY );

if( rc == RFC_OK )
   rc = RfcReceive( handle, .... );
...

@ex Using RfcListen and RfcDispatch. |

RFC_RC     rc;
RFC_HANDLE handle = RfcAccept( argv );
...
do
{
  // Waiting for the next RFC request
  for( rc = RFC_RETRY; rc == RFC_RETRY; )
  {
    rc = RfcListen( handle );
    if( rc == RFC_RETRY )
    {
      // while waiting for the next RFC request, do something...
      ....
    }
  }
  if (rc != RFC_OK)
    break;

  rc = RfcDispatch( handle );

} while( rc == RFC_OK );

RfcClose( handle );
exit( 0 );


-----------------------------------------------------------------------------*/
RFC_RC SAP_API RfcListen(
  RFC_HANDLE handle  /* @parm RFC connection handle */
  );

/*-----------------------------------------------------------------------------
@func

After <f RfcAccept> using register mode, this function can be used to wait
for a defined time for new RFC requests. 

The time must be defined in sec (-1: infinit).

If the RFC server program doesn't run in register mode, this call has
the same functionality as RfcListen (immediately returning).

-----------------------------------------------------------------------------*/
RFC_RC SAP_API RfcWaitForRequest(
  RFC_HANDLE handle, /* @parm RFC connection handle */
  RFC_INT    wtime   /* @parm Wait time             */
  );

RFC_RC SAP_API RfcFileArgv(int* argc, char*** PntArgv);

/*---------------------------------------------------------------------------
@func

This function can be used to build up the structures <t RFC_OPTIONS>,
<t RFC_CONNOPT_R3ONLY>, <t RFC_CONNOPT_VERSION_3> or
<t RFC_CONNOPT_CPIC> from the command line.

@comm

The following tokens are recognized in the argv array, which must
be terminated by a NULL entry :

@flag -d <lt>Destination<gt>  | the name of the destination
@flag -c <lt>NNN<gt>          | client (sign on data)
@flag -u <lt>User Id<gt>      | user id
@flag -p <lt>Password<gt>     | password
@flag -l <lt>language<gt>     | language
@flag -3                      | R/3 mode
@flag -2                      | CPIC mode
@flag -t                      | turn trace on
@flag -h <lt>Hostname<gt>        | the name of the target host
@flag -s <lt>NN<gt>              | the system number of the target SAP system
@flag -g <lt>Gateway Host<gt>    | the gateway host (if not specified, the
                          -h option is used)
@flag -x <lt>Gateway Service<gt> | the TCP/IP service of the gateway (
                             default is sapgwNN, where NN is
                             the system number (-s)
@flag -gui | start 'sapgui' to be able to display SAP Dynpros or
             Graphics (R/3 mode only).
@flag -debug | start communication in debug mode (R/3 mode only).

All tokens that were interpreted by RfcConnArgv3 are removed from
the argv array.

@rdesc returns 0.

@xref <f RfcConnArgv>

---------------------------------------------------------------------------*/
int    SAP_API RfcConnArgv3(
 char **                 argv,         /* @parm command line to be parsed. */
 RFC_OPTIONS *           rfc_opt,      /* @parm option structure to
                                        * be filled.
                                        */
 RFC_CONNOPT_CPIC *      connopt_cpic, /* option extension for R/2 connection
                                        * (a valid pointer must be supplied
                                        *  even if you are not using a R/2
                                        *  system).
                                        */
 RFC_CONNOPT_R3ONLY *    connopt_r3only,  /* @parm option extension for R/3 connection
                                           * (a valid pointer must be supplied
                                           *  all the time).
                                           */
 RFC_CONNOPT_VERSION_3 * connopt_version_3 /* @parm option extension for a
                                            * connection
                                            * to a R/3 system of Rel. 3.0
                                            * or later
                                            * (a valid pointer must be supplied
                                            *  all the time).
                                            */
                           );

/*---------------------------------------------------------------------------
@func

This function was used to build up the structures <t RFC_OPTIONS> ,
<t RFC_CONNOPT_R3ONLY> or
<t RFC_CONNOPT_CPIC> from the command line in former releases and
is included for backward compatibility.

It offers the same functionality as <f RfcConnArgv3> allocating
a static instance of <t RFC_CONNOPT_VERSION_3> internally, however.

Use the function <f RfcConnArgv3> instead, if you are not working
on 16-bit Windows.

On 16-bit Windows only RfcConnArgv is supported.

@rdesc returns 0.

@xref <f RfcConnArgv3>

---------------------------------------------------------------------------*/

int    SAP_API RfcConnArgv(
 char **                 argv,         /* @parm command line to be parsed. */
 RFC_OPTIONS *           rfc_opt,      /* @parm option structure to be filled. */
 RFC_CONNOPT_CPIC *      connopt_cpic, /* option extension for R/2 connection
                                        * (a valid pointer must be supplied
                                        *  even if you are not using a R/2
                                        *  system).
                                        */
 RFC_CONNOPT_R3ONLY *    connopt_r3only   /* @parm option extension for R/3 connection
                                           * (a valid pointer must be supplied
                                           *  all the time).
                                           */
                           );

RFC_RC SAP_API RfcSendSystemInfo( RFC_HANDLE handle );
RFC_RC SAP_API RfcSendPing      ( RFC_HANDLE handle );
RFC_RC SAP_API RfcSendDocu      ( RFC_HANDLE handle );

/* @cb  RFC_RC |  RFC_ONCALL |
 *
 * type of C function to be installed by <f RfcInstallFunction>
 * or <f RfcInstallFunctionExt>.
 *
 */
typedef RFC_RC ( DLL_CALL_BACK_FUNCTION_PTR RFC_ONCALL ) (
   RFC_HANDLE handle /* Handle to RFC connection, from where the RFC parameters
                      * must be read and to which the parameters must be returned.
                      */
               );

/*--------------------------------------------------------------------------
@func

Used to install a function to be callable as RFC function module.

For receiving an RFC call there are two possible ways. The most
simple way to receive an RFC call in an external program is to
register a C function to be called if a call request is received.

The function RfcInstallFunction registers a C function to be
called when receiving the request for an RFC call.

The function pointer points to a function of type <f RFC_ONCALL>,
which contains the functionality being offered as an RFC function
module. 'functionname' is the name of the offered RFC function
module and description should contain a description of  the
functionality as well as a description of the interface. Newline
characters can be used to start new lines.

The descriptions of the registered functions can be requested by
calling the standard function module RFC_DOCU being available in
every RFC server program using <f RfcDispatch> interface.

After <f RfcAccept> or after receiving the return code <e RFC_RC.RFC_CALL>,
when calling <f RfcReceive> the program has to call <f RfcDispatch>,
which internally calls the corresponding registered function.

@rdesc
returns <e RFC_RC.RFC_OK> or <e RFC_RC.RFC_FAILURE>, if there is no memory available
to register the function.

@xref <f RfcDispatch>, <f RfcGetName>

@comm
This function is not available for 16-Bit Windows (Windows 3.x).
Use <f RfcInstallFunctionExt> instead.
 --------------------------------------------------------------------------*/
RFC_RC SAP_API RfcInstallFunction(
 RFC_FUNCTIONNAME functionname,  /* @parm name of function as it can be called
                                  * from ABAP/4 environment. Null terminated
                                  * string.
                                  */
 RFC_ONCALL       f_ptr,         /* @parm function to be called. Must be of type
                                  * <f RFC_ONCALL>.
                                  */
 char *           docu           /* @parm text describing the functionality and
                                  * the parameters of the function module.
                                  */
                                 );

/*-------------------------------------------------------------------------------
@func

Alternate function replacing <f RfcInstallFunction> for Windows 3.x (16-Bit).
The functions needs a valid RFC handle as an additional parameter.

The function module is installed only for the given RFC connection.

@rdesc
returns <e RFC_RC.RFC_OK> or <e RFC_RC.RFC_FAILURE>, if there is no memory available
to register the function.

@xref <f RfcInstallFunction>, <f RfcDispatch>, <f RfcGetName>

@comm
The function is available on all supported platforms to ease porting.
-----------------------------------------------------------------------------------*/
RFC_RC SAP_API RfcInstallFunctionExt(
 RFC_HANDLE handle,              /* @parm valid RFC connection handle,
                                  * as returned by <f RfcAccept>.
                                  */
 RFC_FUNCTIONNAME functionname,  /* @parm name of function as it can be called
                                  * from ABAP/4 environment. Null terminated
                                  * string.
                                  */
 RFC_ONCALL       f_ptr,         /* @parm function to be called. Must be of type
                                  * <f RFC_ONCALL>.
                                  */
 char *           docu           /* @parm text describing the functionality and
                                  * the parameters of the function module.
                                  */

  );

/* @func
 * function to be called to process the next RFC request.
 *
 * After <f RfcAccept> or after receiving the return code
 * <e RFC_RC.RFC_CALL>, when calling <f RfcReceive> or
 * <f RfcCallReceive> the program has to call this function
 * to process the pending RFC request.
 *
 * This function internally calls
 * the registered function corresponding to the RFC call.
 * The return code of the registered function is again
 * returned by RfcDispatch.
 *
 * @comm
 * There are some function modules, which are always
 * offered automatically, when using RfcDispatch.
 *
 * These are
 * @flag RFC_DOCU | get of list of the installed function
 *                  modules.
 * @flag RFC_PING | do nothing, used for connection test.
 * @flag RFC_SYSTEM_INFO | deliver some information on
 *                         the RFC library used.
 *
 * @rdesc
 * returns <e RFC_RC.RFC_OK> or other <t RFC_RC> return code.
 *
 * @ex a typical RFC server |
 *
 * int main ( int argc, char ** argv )
 * {
 *   RFC_HANDLE handle;
 *   RFC_RC     rc;
 *
 *   handle = RfcAccept( argv );
 *   if ( handle == RFC_HANDLE_NULL )
 *   {
 *      ... error processing
 *      return 1;
 *   }
 *
 *   rc = RfcInstallFunction( ..... );
 *   if( rc != RFC_OK )
 *   {
 *      ... error processing
 *      return 1;
 *   }
 *
 *   do
 *   {
 *      rc = RfcDispatch( handle );
 *   }
 *   while( rc == RFC_OK );
 *
 *   RfcClose( handle );
 *
 *   return 0;
 * }
 *
 */
RFC_RC SAP_API RfcDispatch(
  RFC_HANDLE  handle   /* @parm handle to RFC connection */
   );

/* @cb  int |  RFC_ON_CHECK_TID |
 *
 * function to be installed by <f RfcInstallTransactionControl>.
 *
 * The function is called when a local transaction is starting.
 * Since a transactional RFC call can be issued many times
 * by the client system, the function is responsible for storing
 * the transaction ID in permanent storage.
 * If the client system
 * tries starting the same transaction
 * a second time, the function has to return 1.
 *
 * @comm
 * If this functions has access to a SQL database,
 * it should perform a operation like
 *
 *    Insert Into SomeTable values ( :transactionId );
 *
 * where the table 'SomeTable' must have a unique index
 * over the transaction ID. If another process has also inserted
 * the same transaction ID, the second process has to wait until
 * the transaction is completed by the first process. If the
 * transaction is completed by another process (The Insert command
 * returns with some 'Duplicate Record' error code, the function must
 * return 1 to indicate to skip the transaction.
 *
 * @rdesc
 * return values
 * @flag 0      | transaction ID stored, transaction can be started.
 * @flag 1      | transaction already done, skip the request.
 * @flag <lt> 0 | cannot lock transaction, internal error.
 *
 *
 */
typedef int ( DLL_CALL_BACK_FUNCTION_PTR RFC_ON_CHECK_TID )(
  RFC_TID transactionId  /* @parm actual transaction ID */
   );

/* @cb  int |  RFC_ON_COMMIT |
 *
 * function to be installed by <f RfcInstallTransactionControl>.
 *
 * The function is called when a local transaction ends.
 *
 * The function is to be used to commit the local transaction,
 * if necessary.
 *
 * @comm
 * If this functions has access to a SQL database,
 * it should perform a operation like
 *
 *    Commit work;
 *
 */
typedef void ( DLL_CALL_BACK_FUNCTION_PTR RFC_ON_COMMIT )
(
    RFC_TID transactionId  /* @parm transaction ID */
);


/* @cb  int |  RFC_ON_ROLLBACK |
 *
 * function to be installed by <f RfcInstallTransactionControl>.
 *
 * The function is called when a local transaction ends with failure.
 *
 * The function is to be used to roll back the local transaction,
 * if necessary.
 *
 * @comm
 * If this functions has access to a SQL database,
 * it should perform a operation like
 *
 *    Rollback work;
 *
 */
typedef void ( DLL_CALL_BACK_FUNCTION_PTR RFC_ON_ROLLBACK )
(
    RFC_TID transactionId  /* @parm transaction ID */
);


/* @cb  void |  RFC_ON_CONFIRM_TID |
 *
 * function to be installed by <f RfcInstallTransactionControl>.
 *
 * The function is called when a local transaction is completed.
 * All information stored about that transaction can be discarded
 * by the server.
 *
 * In general this function can be used to delete the transaction
 * ID from permanent storage.
 *
 * @comm
 * If this functions has access to a SQL database,
 * it should perform a operation like
 *
 *    Delete From SomeTable where key = :transactionId; Commit Work;
 *
 * where the table 'SomeTable' should have a unique index
 * over the transaction ID.
 *
 *
 *
 */
typedef void ( DLL_CALL_BACK_FUNCTION_PTR RFC_ON_CONFIRM_TID )
(
    RFC_TID transactionId  /* @parm transaction ID */
);

/* @func
 *
 * installs 4 functions to control transactional behavior.
 * Only to be used with transactional RFC.
 *
 * Must be called by
 * RFC server program before the RfcDispatch loop is entered,
 * if this program wants to receive transactional RFC calls,
 * i.e. calls being issued by 'Call Function ... In Background Task'
 * and must ensure, that RFC calls are done exactly once.
 *
 * Without installing these functions it can only be guaranteed,
 * that an RFC function call issued by
 * 'Call Function ... In Background Task'
 * is done at least once. Then all function modules offered by such a server
 * program, which are called via 'Call Function ... In Background Task'
 * must cope with being called more then once.
 *
 * If installed, the first function onCheckTid is called, if a transactional
 * RFC is to be called. The actual Transaction ID
 * is passed ( <f RFC_ON_CHECK_TID> ).
 * The function has to store this transaction id in permanent
 * storage and return 0 .
 * If the same function will be called later again with the same
 * Transaction Id, it has to make sure that it will
 * return a non-zero value.
 * If the same transaction is already
 * running by another process, but is not completed,
 * the function has to wait, until
 * the transaction completes.
 *
 * The second function is called, if all the RFC function module
 * calls are done and the local transaction can be completed.
 * It should be used, to locally commit the transaction, if necessary
 * ( <f RFC_ON_COMMIT> ).  This function is 'void' .
 *
 * The third function is called instead of the 2nd function,
 * if, from the point of view of the RFC library,
 * there occurred an error while processing the local transaction.
 * This function can be used to roll back the local transaction
 * ( <f RFC_ON_ROLLBACK> ). This function is 'void' .
 *
 * The 4th function will be called, if the local transaction is
 * completed also from the point of view of the calling system
 * and all information on this transaction Id can be
 * discarded. This function is 'void' .
 * <f RFC_ON_CONFIRM_TID>
 *
 * @xref <t RFC_TID>
 */
void SAP_API RfcInstallTransactionControl (
 RFC_ON_CHECK_TID   onCheckTid, /* @parm function to be called, when
				 * local transaction starts. Must be used
                                 * to check, if the transaction is already
                                 * running or was already completed.
				 */
 RFC_ON_COMMIT      onCommit,   /* @parm function to be called, when
                                 * local transaction ends.
                                 * Should be used to commit the
                                 * transaction locally.
                                 */
 RFC_ON_ROLLBACK    onRollback, /* @parm function to be called, if
                                 * local transaction fails due to an
                                 * error found while the processing
                                 * is done inside the RFC library.
                                 * Should be used to roll back
                                 * a local transaction.
                                 */
 RFC_ON_CONFIRM_TID onConfirmTid /* @parm function to be called, when
				  * local transaction is confirmed.
                                  * All information stored locally about
                                  * this transaction can be deleted.
				  */
					);

/* SAP->API: info transact. rfc */

RFC_RC SAP_API RfcGetTrfcInfo( char * user, char * dest );


/* SAP->API: get transactionID and set f_ptr for confirmation */

RFC_RC SAP_API RfcGetTransID( RFC_RC (* _SYSTEM f_ptr)( char * ),
					   RFC_TID tid );

/* @func
 *
 * Get a Transaction-ID for a following call of a function module in R/3
 * using the transactional RFC interface in R/3
 *
 * With this function a new TransID will be produced from the R/3 system
 * the RFC client program has to call a function module in R/3 via
 * <f RfcIndirectCall> with this TransID.
 *
 * If an error occurs (e.g. communication error) during the call of a function
 * module in R/3 via RfcIndirectCall the RFC client program has to reconnect
 * the RFC connection and repeat the RfcIndirectCall without creating a new TransID
 *
 * @xref <f RfcIndirectCall>, <t RFC_TID>
*/
RFC_RC SAP_API RfcCreateTransID(  RFC_HANDLE  handle,
				  RFC_TID     tid );
/* API->SAP: check transID already is enqueued                */

RFC_RC SAP_API RfcCheckTransID(   RFC_HANDLE  handle,
                           	  RFC_TID     tid       );
/* API->SAP: clear transID on SAP R/3                         */

RFC_RC SAP_API RfcConfirmTransID( RFC_HANDLE  handle,
                            	  RFC_TID     tid       );
/* Internal use */

RFC_HANDLE RfcLocalOpen( char * name );

/*
    New API functions that omit the use of structs.
    d002076, 28.1.94
*/
typedef struct
{
	RFC_INT MaxNo;
    void* Params;
}RFC_PARAMETER_STACK;

typedef struct
{
    RFC_PARAMETER_STACK Exports;
    RFC_PARAMETER_STACK Imports;
    RFC_PARAMETER_STACK Tables;
} RFC_PARAMETER_ADMIN;

typedef RFC_PARAMETER_ADMIN* RFC_PARAM_SPACE;

RFC_PARAM_SPACE SAP_API RfcAllocParamSpace(unsigned MaxEx,
				 unsigned MaxIm,
				 unsigned MaxTab);

RFC_RC SAP_API RfcFreeParamSpace(RFC_PARAM_SPACE PSpace);

RFC_RC SAP_API RfcAddExportParam(RFC_PARAM_SPACE PSpace,
                                 unsigned ParamNo,
                                 void* name,
                                 unsigned nlen,
                                 unsigned type,
                                 unsigned leng,
                                 void* addr);

RFC_RC SAP_API RfcAddImportParam(RFC_PARAM_SPACE PSpace,
                                 unsigned ParamNo,
                                 void* name,
                                 unsigned nlen,
                                 unsigned type,
                                 unsigned leng,
                                 void* addr);

RFC_RC SAP_API RfcAddTable ( RFC_PARAM_SPACE PSpace,
                                 unsigned TableNo,
                                 void* name,
                                 unsigned nlen,
                                 unsigned type,
                                 unsigned leng,
                                 ITAB_H ithandle);

ITAB_H SAP_API RfcGetTableHandle(RFC_PARAM_SPACE PSpace,
				 unsigned TableNo);

RFC_RC SAP_API RfcCallExt ( RFC_HANDLE handle,
				RFC_PARAM_SPACE PSpace,
	   			char* function);

RFC_RC SAP_API RfcReceiveExt(RFC_HANDLE handle,
				RFC_PARAM_SPACE PSpace,
	        		char* exception);

RFC_RC SAP_API RfcCallReceiveExt(RFC_HANDLE handle,
				 RFC_PARAM_SPACE PSpace,
		    		 char* function,
				char* exception);

RFC_RC SAP_API RfcIndirectCallExt(RFC_HANDLE handle,
				  RFC_PARAM_SPACE PSpace,
				  char* function,
				  RFC_TID tid);

RFC_RC SAP_API RfcGetDataExt(RFC_HANDLE handle,
				 RFC_PARAM_SPACE PSpace);

RFC_RC SAP_API RfcSendDataExt(RFC_HANDLE handle,
				 RFC_PARAM_SPACE PSpace);

int SAP_API RfcExecProgram( char * c,
		            char * et,
		            unsigned leng );
		
RFC_INT SAP_API RfcGetVersion(void);
RFC_RC SAP_API RfcCheckVersionsOfUsedLibs(void);
RFC_RC SAP_API RfcGetAllLibVersions(char* buffer, int BufferLength);

#ifdef SAPGUI
/* ------------------------------------------------------------------
 *  functions must only be used by 'sapgui'
 * ----------------------------------------------------------------*/
SAP_BOOL SAP_API TrRfcRequest (SAP_BYTE* rfcinput,
			       SAP_BYTE* rfcoutput,
			       int       outlength );
RFC_RC SAP_API RfcSapguiRequest ( RFC_HANDLE handle,
			       SAP_BYTE* rfcinput,
			       SAP_BYTE* rfcoutput,
			       int       outlength );
SAP_BOOL SAP_API TrRfcRequest2 ( SAP_BYTE* rfcinput,
				 SAP_BYTE* rfcoutput,
				 int       outlength,
				 int       modno );
void SAP_API RfcSapguiExit( RFC_HANDLE handle );
RFC_HANDLE SAP_API RfcSapguiInit( void );
#endif

#ifdef __cplusplus
}
#endif

#endif /* SAPRFC_H */
#endif /* RFC_H */

