/*
	File:		sat.h
	Description:	Include file for satellite program.
	Author:		T.E. Carone

*/

/*
	Define the TUXEDO error code that is used to determine if a particular TUXEDO
		function call failed.  If so, a transaction rollback occurs.
*/
#define		TUXEDO_ERROR		-1

/*
	Flags for TUXEDO service calls.  Most TUXEDO functions have reserved the FLAGS
		argument for future use.  Therefore, they are not used here.
*/
#define		SAT_TUXEDO_FLAGS	0L
#define		SAT_SUCCESS	0
#define		SAT_FAIL	-1

/*
	The following structures are for use in the marshaling functions.
		They are used to transfer information to the service logic
		function and then back to the client.
*/

struct GTS_IN{
	char	NameOfSatellite[32];
};

struct GTS_OUT{
	double	p1;
	double	p2;
	double	p3;
	double	p4;
	double	p5;
	double	p6;
	double	p7;
	double	p8;
	double	p9;
	double	p10;
	double	p11;
	double	p12;
	double	p13;
};

struct CNSP_IN{
	double	p1;
	double	p2;
	double	p3;
	double	p4;
	double	p5;
	double	p6;
	double	p7;
	double	p8;
	double	p9;
	double	p10;
	double	p11;
	double	p12;
	double	p13;
	char	NewTimeAndDate[32];
};

struct CNSP_OUT{
	double	xpos;
	double	ypos;
	double	zpos;
	double	xvel;
	double	yvel;
	double	zvel;
};

struct USP_IN{
	double	xpos;
	double	ypos;
	double	zpos;
	double	xvel;
	double	yvel;
	double	zvel;
	char	NewTimeAndDate[32];
};

struct USP_OUT{
	char	TheResult[256];
};


/*
	This is the output from the viewc compiler.  It took the file
		sat_TUXEDO_VIEWS.v file and produced this file which is
		then included in the source code files.
*/

/*
	The input and output buffers for GetTheSatellite.  The p1 - p13
		structure elements are the 13 elements that make up the
		NORAD general perturbation elements.  Their precise
		definition can be found in pub/space/spacetrk.doc (a LaTeX file)
		at archive.afit.af.mil.
*/
struct SVC_GTS_IN {
	char	NameOfSatellite[32];
};

struct SVC_GTS_OUT {
	double	p1;
	double	p2;
	double	p3;
	double	p4;
	double	p5;
	double	p6;
	double	p7;
	double	p8;
	double	p9;
	double	p10;
	double	p11;
	double	p12;
	double	p13;
};

/*
	The input and output buffers for CalcNewSatellitePosition.  The output
		buffer contains the new three position coordinates for the
		satellite and the new three velocity coordinates for the
		satellite.
*/
struct SVC_CNSP_IN {
	double	p1;
	double	p2;
	double	p3;
	double	p4;
	double	p5;
	double	p6;
	double	p7;
	double	p8;
	double	p9;
	double	p10;
	double	p11;
	double	p12;
	double	p13;
	char	NewTimeAndDate[32];
};

struct SVC_CNSP_OUT {
	double	xpos;
	double	ypos;
	double	zpos;
	double	xvel;
	double	yvel;
	double	zvel;
};

/*
	The input and output buffers for UpdateSatellitePosition.
*/
struct SVC_USP_IN {
	double	xpos;
	double	ypos;
	double	zpos;
	double	xvel;
	double	yvel;
	double	zvel;
	char	NewTimeAndDate[32];
};

struct SVC_USP_OUT {
	char	TheResult[256];
};


/*

	File:		sat_client.c
	Author:		T.E. Carone

	This application shows a simple use of Tuxedo.  A client program performs
		a simple transaction.  The client needs to estimate the future
		position of the Extreme Ultraviolet Explorer (EUVE) astronomical
		satellite using the general orbital perturbation element sets generated
		and maintained by the NORAD.  This information has been stored in an
		Oracle database.

	This is the client program that will use Tuxedo to manage the transaction and
		return information from the Oracle database.  The client performs the
		following steps:

		1.  Joins Tuxedo using tpinit().
		2.  Starts a transaction using tpbegin().
		3.  Calls the GetTheSatellite Tuxedo service to get the information
			on the EUVE satellite that is contained in the Oracle
			database.
		4.  Calls the CalcNewSatellitePosition Tuxedo service to calculate the
			future position of the EUVE satellite given the NORAD
			information.
		5.  Calls the UpdateSatellitePosition Tuxedo service to update the
			position of the EUVE satellite at a future time.  This
			information is also contained in the database.
		6.  Commits the transaction using tpcommit() if all Tuxedo services
			executed properly or it issues a tpabort() to rollback the
			transaction.
		7.  Disconnects from Tuxedo using tpterm().

	This example shows the request/reply mode of communication.


	This example uses the NORAD two-line general orbital perturbation element
		sets.  This information is posted regularly to sci.space.news and
		to rec.radio.amateur.space.
*/

#include <stdio.h>

/*
	Client header file.
*/
#include <sat.h>

/*
	atmi.h is the TUXEDO-supplied include file.
*/
#include <atmi.h>

#define USER_NAME       "Carone"
#define PASSWORD        "EUVE"

int main()
{

/*
	Declare the input and output buffer names for each of the three services.
		These will point to the buffers defined in sat_TUXEDO_VIEWS.v and
		sat_TUXEDO_VIEWS.h.  GTS refers to the GetTheSatellite TUXEDO service,
		CNSP refers to the CalcNewSatellitePosition TUXEDO service, and USP
		refers to the UpdateSatellitePosition TUXEDO service.
*/

struct	SVC_GTS_IN	*svc_GTS_inbuf;
struct  SVC_GTS_OUT	*svc_GTS_outbuf;
struct	SVC_CNSP_IN	*svc_CNSP_inbuf;
struct  SVC_CNSP_OUT	*svc_CNSP_outbuf;
struct	SVC_USP_IN	*svc_USP_inbuf;
struct  SVC_USP_OUT	*svc_USP_outbuf;

/*
	Declare the return code variable that is assigned the return code from TUXEDO
		service invocations.
*/
int     iRetCode;

/*
	Declare the variable that will contain the length of the output buffer that
		is returned from TUXEDO service invocations.
*/
long    lRetLen;

/*
	Connect to TUXEDO using tpinit().  If the connection is successful then
		allocate the TUXEDO buffers (both the buffer sent to the service with
		the name of the satellite and the buffer that returns the satellite
		information from the service) for the first service, GetTheSatellite.

*/
iRetCode = tpinit(NULL);
if (iRetCode != TUXEDO_ERROR){

/*
	Allocate the buffers using tpalloc().
*/
	svc_GTS_inbuf = (struct SVC_GTS_IN *) tpalloc("VIEW", "GTS_IN",
			sizeof(struct SVC_GTS_IN));
	svc_GTS_outbuf = (struct SVC_GTS_OUT *) tpalloc("VIEW", "GTS_OUT",
			sizeof(struct SVC_GTS_OUT));
	svc_CNSP_inbuf = (struct SVC_CNSP_IN *) tpalloc("VIEW", "CNSP_IN",
			sizeof(struct SVC_CNSP_IN));
	svc_CNSP_outbuf = (struct SVC_CNSP_OUT *) tpalloc("VIEW", "CNSP_OUT",
			sizeof(struct SVC_CNSP_OUT));
	svc_USP_inbuf = (struct SVC_USP_IN *) tpalloc("VIEW", "USP_IN",
			sizeof(struct SVC_USP_IN));
	svc_USP_outbuf = (struct SVC_USP_OUT *) tpalloc("VIEW", "USP_OUT",
			sizeof(struct SVC_USP_OUT));

/*
	Fill the GetTheSatellite TUXEDO service input buffer with the name of the
		satellite that is to be retrieved from the Oracle database.
*/
	strcpy(svc_GTS_inbuf->NameOfSatellite, "EUVE");

/*
	Begin the transaction using tpbegin().  The 60 sets the transaction timeout
		to 60 seconds.
*/
        iRetCode = tpbegin(60, SAT_TUXEDO_FLAGS);
        if (iRetCode != TUXEDO_ERROR){

/*
	Invoke the GetTheSatellite TUXEDO service using tpcall().  This is a
		synchronous call; therefore the client must wait until TUXEDO
		returns control.  It is necessary to recast the pointers to the
		input and output buffers.
*/
		iRetCode = tpcall("GetTheSatellite",
					(char *)svc_GTS_inbuf, sizeof(struct SVC_GTS_IN),
					(char **)&svc_GTS_outbuf, &lRetLen,
					SAT_TUXEDO_FLAGS);

		if (iRetCode != TUXEDO_ERROR){

/*
	Copy the contents of the svc_GTS_outbuf TUXEDO buffer to the svc_CNSP_inbuf
		buffer and invoke the CalcNewSatellitePosition TUXEDO service.
*/
			svc_CNSP_inbuf = (struct SVC_CNSP_IN *) svc_GTS_outbuf;
			strcpy(svc_CNSP_inbuf->NewTimeAndDate, "5/8/1997");

			iRetCode = tpcall("CalcNewSatellitePosition",
					(char *)svc_CNSP_inbuf, sizeof(struct SVC_CNSP_IN),
					(char **)&svc_CNSP_outbuf, &lRetLen,
					SAT_TUXEDO_FLAGS);

			if (iRetCode != TUXEDO_ERROR){

/*
	Copy the contents of the svc_CNSP_outbuf TUXEDO buffer to the svc_USP_inbuf
		buffer and invoke the UpdateSatellitePosition TUXEDO service.
*/
			svc_USP_inbuf = (struct SVC_USP_IN *) svc_CNSP_outbuf;
			strcpy(svc_USP_inbuf->NewTimeAndDate, svc_CNSP_inbuf->NewTimeAndDate);

			iRetCode = tpcall("UpdateSatellitePosition",
					(char *)svc_USP_inbuf, sizeof(struct SVC_USP_IN),
					(char **)&svc_USP_outbuf, &lRetLen,
					SAT_TUXEDO_FLAGS);

/*
	If the UpdateSatellitePosition was successful then commit the transaction.
		Otherwise, rollback the transaction.
*/
			if (iRetCode != TUXEDO_ERROR)
				tpcommit(SAT_TUXEDO_FLAGS);
			else
				tpabort(SAT_TUXEDO_FLAGS);
			}

/*
	If the GetSatellitePosition or the CalcNewSatellitePosition TUXEDO services
		failed then rollback the transaction.
*/
		else
			tpabort(SAT_TUXEDO_FLAGS);
		}

	else
		tpabort(SAT_TUXEDO_FLAGS);
	}


/*
	Free the allocated buffers and disconnect from TUXEDO using tpterm().
*/
        tpfree((char *) svc_GTS_inbuf);
        tpfree((char *) svc_GTS_outbuf);
        tpfree((char *) svc_CNSP_inbuf);
        tpfree((char *) svc_CNSP_outbuf);
        tpfree((char *) svc_USP_inbuf);
        tpfree((char *) svc_USP_inbuf);
    	iRetCode = tpterm();
    }
return;
}
