/**********************************************************************
 * Copyright (c) 2005, 2009 IBM Corporation and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * $Id: RAComm.h,v 1.9 2009/07/10 00:11:38 jwest Exp $
 *
 * Contributors:
 * IBM - Initial API and implementation
 **********************************************************************/

#ifndef _RACOMM_H_
#define _RACOMM_H_

/* Provide unified string access methods across all platforms. */
#if defined(__cplusplus) && (defined(_HPUX) || defined(__powerpc64__) || defined(_AIX))
 #define ENV(e) e
 #define ENVPARM(e)
 #define ENVPARM1(e)
#else
 #define ENV(e) (*e)
 #define ENVPARM(e) e,
 #define ENVPARM1(e) e
#endif


/**
  * Platform specific includes.
  */
#ifdef _WIN32										/* Win32 */
	#include <windows.h>
	#include <winbase.h>
#else												/* else */
	#include <pthread.h>
	#include <arpa/inet.h>
	#if defined(__OS400__)  || defined(MVS)
 		#include <stdlib.h>
 		#ifdef MVS
			/*  228721 - for 390, strings.h is needed to define bzero() */
			#include <strings.h>
		#endif
		/* 190770 - for 390, including string.h causes run-time
		library functions to be inlined to improve performance */
		#include <string.h>
	#else
		#include <strings.h>
	#endif
#endif

#ifdef _HPUX
	#include <string.h>
	#include <malloc.h>
	#include <unistd.h>
#endif

/* Mutex */
#ifdef _WIN32
	#define ra_critsec_t CRITICAL_SECTION
#else
	#define ra_critsec_t pthread_mutex_t
#endif

/**
  * Macros/typedefs to ease the readability of multiplatform code.
  */
#ifdef _WIN32										/* Win32 */
 #define BZERO(mem, len) ZeroMemory(mem,len)
 #define SLEEP(millisec) Sleep(millisec)
 #define STRDUP(dest, src)  dest=strdup(src)
 #define PATH_SEPARATOR ';'
 #define FILE_SEPARATOR '\\'
 typedef DWORD TID;
 typedef DWORD PID;
 typedef HANDLE RA_HANDLE;
 #define RA_HANDLE_NULL	NULL
 #define CLOSE_RA_HANDLE(handle)		CloseHandle(handle)
#else												/* else */
 #define _MAX_PATH 256 /* This is already defined on Windows */
 #if defined (__OS400__)
  #define BZERO(mem, len) memset(mem, '\0', len)
  #define STRDUP(dest, src)  dest=(char*)malloc(strlen(src)+1); BZERO(dest, strlen(src)+1); strcpy(dest, src) /* 236501 */
 #elif defined (_HPUX)
  #define BZERO(mem, len) memset(mem, '\0', len)
  #define STRDUP(dest, src)  dest=strdup(src)
 #else
  #define BZERO(mem, len) bzero(mem,len)
  #define STRDUP(dest, src)  dest=strdup(src)
 #endif
 #define PATH_SEPARATOR ':'
 #define FILE_SEPARATOR '/'
 #define RA_HANDLE_NULL 0
 #define CLOSE_RA_HANDLE(handle)		close(handle)
 #define WINAPI " "
#endif


/* The master adddress of the RAC */
#define RA_MASTER_ADDRESS			"ramaster"
#ifdef _WIN32
 #define RA_PIPE_NAMESPACE			"\\\\.\\pipe\\IBMAC\\"
#else
 #define RA_PIPE_NAMESPACE			"/tmp/IBMRAC/"
 #define RA_PIPE_NAMESPACE_SHORT	"/tmp/IBMRAC"
#endif

/**
  * Remoteable Agent Data Types
  */
#if defined(__powerpc64__) || defined(__ia64__) || defined(__x86_64__) || defined(_LP64) || (defined(__linux__) && defined(__s390x__)) || (defined(__64BIT__) && defined(_AIX)) /* long is 8 bytes, int is 4 bytes in size on 64-bit */
	typedef unsigned int ra_uint_t;
	typedef signed int ra_int_t;
#else
	typedef unsigned long ra_uint_t;
	typedef signed long ra_int_t;
#endif

typedef struct {
	ra_uint_t length;
	char *data;
}ra_string_t;

typedef struct {
	ra_uint_t length;
	void **data;
}ra_array_t;


typedef struct {
	ra_string_t type;
	ra_string_t name;
	ra_string_t value;
}ra_agentConfigEntry_t;

/**
 * GENERAL PROTOCOL FORMAT:
 */

/* Constant portion of the header */
#define RA_MAGIC		0x82656780
#define RA_VERSION		0x00000100

/* The message types */
#define RA_ACKNOWLEDGEMENT_MESSAGE		0x00000000
#define RA_CONTROL_MESSAGE				0x00000001



/* The structure of a COMMAND */
typedef struct {
	ra_uint_t tag;								/* COMMAND_ID */
	union {
		struct {
			ra_string_t user;
			ra_string_t passwd;
		}authenticate;							/* AUTHENTICATE */

		struct {
			ra_string_t key;
		}authenticate_successful;				/* AUTHENTICATION_SUCCESSFUL */

		struct {
			ra_uint_t ticket;
		}authenticate_failed;					/* AUTHENTICATION_FAILED */


        struct {
            ra_uint_t flag;
            ra_uint_t securePort;
        }serverSecurityRequirements;            /* RA_SERVER_SECURITY_REQUIREMENTS */

		struct {
			ra_uint_t context;
			ra_uint_t consoleIP;
			ra_uint_t consolePort;
			ra_string_t executable;
			ra_string_t arguments;
			ra_string_t location;
			ra_array_t environment;
			ra_array_t agents;
		}launch_process;						/* LAUNCH_PROCESS*/

		struct {
			ra_uint_t context;
			ra_uint_t processId;
			ra_string_t processUUID;
			ra_string_t executable;
			ra_string_t arguments;
			ra_array_t environment;
		}process_launched;						/* PROCESS_LAUNCHED */

		struct {
			ra_uint_t context;
		}query_process_list;					/* QUERY_PROCESS_LIST */

		struct {
			ra_uint_t context;
			ra_array_t processes;
		}registered_process_list;				/* REGISTERED_PROCESS_LIST */

		struct {
			ra_uint_t context;
			ra_uint_t processId;
		}query_agent_list,						/* QUERY_AGENT_LIST */
		 kill_process,							/* KILL_PROCESS */
		 process_exited;						/* PROCESS_EXITED */

		struct {
			ra_uint_t context;
			ra_uint_t processId;
			ra_string_t executable;
			ra_array_t agents;
		}registered_agents_list;				/* REGISTERED_AGENTS_LIST */

		struct {
			ra_uint_t context;
			ra_uint_t  processId;
			ra_string_t agent;
		}register_agent_notification,			/* REGISTER_AGENT_NOTIFICATION */
		 query_agent_details;					/* QUERY_AGENT_DETAILS */

		struct {
			ra_uint_t context;
			ra_uint_t processId;
			ra_string_t agent;
		}attach,								/* ATTACH */
		 detach,								/* DETACH */
		 stop_monitor,							/* STOP MONITOR */
		 agent_query_state,						/* AGENT_QUERY_ATTACHED */ /* Bug 54376 */
		 agent_state;							/* AGENT_ATTACHED, AGENT_DETACHED */ /* Bug 54376 */

		struct {
			ra_uint_t context;
			ra_uint_t processId;
			ra_string_t agent;
			ra_uint_t ip;
			ra_uint_t port;
		}start_monitor_remote;					/* START_MONITOR_REMOTE */

		struct {
			ra_uint_t context;
			ra_uint_t processId;
			ra_string_t agent;
			ra_string_t file;
		}start_monitor_local;					/* START_MONITOR_LOCAL */

		struct {
			ra_uint_t context;
			ra_uint_t processId;
			ra_string_t agent;
			ra_string_t type;
			ra_string_t name;
			ra_string_t value;
		}set_nv_pair;							/* SET_NV_PAIR */

		struct {
			ra_uint_t context;
			ra_uint_t processId;
			ra_string_t agent;
			ra_string_t message;
		}custom_command;						/* CUSTOM_COMMAND */

		struct {
			ra_uint_t context;
			ra_uint_t processId;
			ra_string_t agent;
			ra_uint_t severity;
			ra_string_t messageId;
			ra_string_t message;
		}error_string;							/* ERROR_STRING */

		struct {
			ra_uint_t context;
			ra_uint_t processId;
			ra_string_t processUUID;
			ra_string_t agent;
			ra_string_t agentUUID;
			ra_string_t agentType;
		}agent_active,							/* AGENT_ACTIVE */
		 agent_inactive,						/* AGENT_INACTIVE */
		 agent_details;							/* AGENT_DETAILS */

		struct {
			ra_uint_t context;
			ra_uint_t processId;
/* BEGIN:  235649 */
#if defined __linux__
			ra_uint_t messageProcessId;
#endif
/* END: 235649 */
			ra_string_t processUUID;
			ra_string_t agent;
			ra_string_t agentUUID;
			ra_string_t agentType;
			ra_string_t nodeUUID;
		}agent_scoping_information;				/* AGENT_SCOPING_INFORMATION */

		struct {
			ra_uint_t context;
			ra_uint_t processId;
			ra_string_t processUUID;
			ra_string_t agent;
			ra_string_t agentUUID;
			ra_string_t agentType;
			ra_string_t nodeUUID;
			ra_array_t  configuration;
		}agent_configuration;					/* AGENT_CONFIGURATION */

		struct {
			ra_uint_t context;
			ra_uint_t processId;
			ra_string_t agent;
			ra_string_t node;
			ra_uint_t peerProcessId;
			ra_string_t peerAgent;
			ra_string_t peerNode;
		}agent_request_monitor, 				/* AGENT_REQUEST_ATTACH */
		 controller_request_monitor,			/* CONTROLLER_REQUEST_MONITOR */
		 peer_unreachable;						/* PEER_UNREACHABLE */

		/* Bug 77768 begins */
		struct {
			ra_uint_t context;
			ra_uint_t processId;
			ra_string_t agent;
			ra_string_t node;
			ra_uint_t peerProcessId;
			ra_string_t peerAgent;
			ra_string_t peerNode;
			ra_uint_t port;						/* Bug 77768 */
			ra_uint_t peerPort;					/* Bug 77768 */
		}agent_request_monitor_port, 			/* AGENT_REQUEST_ATTACH */
		 controller_request_monitor_port;		/* CONTROLLER_REQUEST_MONITOR */
		/* Bug 77768 ends */

		struct {
			ra_uint_t context;
			ra_string_t name;
			ra_string_t type;
			ra_string_t agentUUID;
		} query_property_list;					/* GET_PROPERTY_LIST */

		struct {
			ra_uint_t context;
			ra_array_t entries;
		} property_list;							/* PROPERTY_LIST */

/** FILE MANAGEMENT STRUCTURES FOR TRANSFERRING HEADPDUMP FILES
  * Modified by Giridhar.S on 11/4/04*/

		struct	{
			ra_uint_t context;
			ra_uint_t operation;
			ra_string_t filename;				/* MANAGE_FILE */
		}manage_file;

		struct	{
			ra_uint_t context;
			ra_uint_t port;
			ra_string_t jobKey;
		}resource_location;

/** END OF MODIFICATIONS TO RACOMM.H **/

		ra_string_t agentName;

	}info;
} ra_command_t;


typedef struct _command_entry_node {
	ra_command_t *command;
	struct _command_entry_node *next;
	struct _command_entry_node *previous;
}ra_command_list_node_t;

typedef struct {
	ra_command_list_node_t *head;
	ra_command_list_node_t *tail;
	ra_uint_t count;
}ra_command_list_t;


typedef struct {
	ra_uint_t type;
	ra_uint_t ticket;
	ra_uint_t length;
	ra_string_t key;
	ra_command_list_t commands;
}ra_message_t;


/* Define an element to be manipulated atomicly */
#ifndef _AIX
typedef int	*atomic_p;
#endif


/* The various COMMAND_ID's types from the client (server targeted flows) */
#define RA_AUTHENTICATE							0x00000001

#define RA_LAUNCH_PROCESS						0x00000010
#define RA_KILL_PROCESS							0x0000001B
#define RA_QUERY_PROCESS_LIST					0x00000011
#define RA_QUERY_AGENT_LIST						0x00000012
#define RA_QUERY_AGENT_DETAILS					0x0000001C
#define RA_REGISTER_AGENT_NOTIFICATION			0x00000013
#define RA_ATTACH_TO_AGENT						0x00000014
#define RA_DETACH_FROM_AGENT					0x00000015
#define RA_START_MONITORING_AGENT_REMOTE		0x00000016
#define RA_START_MONITORING_AGENT_LOCAL			0x00000017
#define RA_STOP_MONITORING_AGENT				0x00000018
#define RA_SET_NAME_VALUE_PAIR					0x00000019
#define RA_GET_PROPERTY_LIST					0x0000001E
/* Changed from 0x00000070 */
#define RA_MANAGE_FILE							0x0000001F



/* The extension point for custom protocol piggy-backing */
#define RA_CUSTOM_COMMAND						0x0000001A
#define RA_BINARY_CUSTOM_COMMAND				0x0000001D


/* The various COMMAND_ID's from the Remoteable Agent Controller (client targeted flows) */
#define RA_AUTHENTICATION_FAILED				0x00000002
#define RA_AUTHENTICATION_SUCCESSFUL			0x00000003
#define RA_SERVER_SECURITY_REQUIREMENTS         0x00000004
#define RA_PROCESS_LAUNCHED						0x00000020
#define RA_PROCESS_EXITED						0x00000029
#define RA_PROCESS_LIST							0x00000021
#define RA_AGENT_LIST							0x00000022
#define RA_AGENT_ACTIVE							0x00000023
#define RA_AGENT_INACTIVE						0x00000024

#define RA_AGENT_DETAILS						0x00000028
#define RA_ERROR_STRING							0x00000025
#define RA_ATTACH_SUCCESSFUL					0x00000026
#define RA_ATTACH_FAILED						0x00000027
#define RA_PROPERTY_LIST						0x0000002A

#define RA_AGENT_QUERY_STATE					0x0000002B /* Bug 54376 */
#define RA_AGENT_ATTACHED						0x0000002C /* Bug 54376 */
#define RA_AGENT_DETACHED						0x0000002D /* Bug 54376 */

/* Services provided by the server for the agents */
#define RA_LOCAL_AGENT_ACTIVE					0x00000030
#define RA_AGENT_SCOPING_INFORMATION			0x00000031
#define RA_AGENT_CONFIGURATION					0x00000032

/* Services provided by the bindings for the agent */
#define RA_AGENT_CONTROLER_AVAILABLE			0x00000050
#define RA_AGENT_CONTROLER_UNAVAILABLE			0x00000051

/* Services for peer to peer actions */
#define RA_AGENT_REQUEST_MONITOR				0x00000061
#define RA_CONTROLLER_REQUEST_MONITOR			0x00000062
#define RA_PEER_UNREACHABLE						0x00000063
#define RA_CONTROLLER_MONITOR_PEER				0x00000064 /* Not being used in native code at all? */
#define RA_AGENT_REQUEST_MONITOR_PORT			0x00000065 /* Temporary solution, should replace RA_AGENT_REQUEST_MONITOR */
#define RA_CONTROLLER_REQUEST_MONITOR_PORT		0x00000066 /* Temporary solution, should replace RA_CONTROLLER_REQUEST_MONITOR */

/* File management ids */
/* Since these constants are internal to RA_MANAGE_FILE command,
   they are not visible outside, and there is no chance of
   collision with other constants with same value */
	
#define RA_GET_FILE								0x00000001
#define RA_PUT_FILE								0x00000002
#define RA_DELETE_FILE							0x00000003

/* We might have to change this */
#define RA_RESOURCE_LOCATION					0x00000070

/* NOOP */
#define RA_NOOP									0x00000040

/**
 * Various constants that both the client and server must adhere to.
 */
#define RA_ACKNOWLEDGEMENT_MESSAGE_LENGTH 16
#define RA_CTL_PORT_NUM_SERVER	10002   /* The agent controller server port */
#define RA_SECURE_PORT_NUM_SERVER 10003;
#define RA_FILE_PORT_NUM_SERVER	10005
/* #define CTL_PORT_NUM_CLIENT		10003    The starting port wher agents will be assigned ports from */
#define MAX_DATA_LENGTH			4096	/* The size of the data buffer for sockets */

/* RKD: TO_DO: Remove the need for these constants */
#define MAX_HOST_NAME_LENGTH	128
/* end TO_DO */

#endif
