/* Application - HPDI32 - Any OS */
/* $Workfile: main.c $ */
/* $Revision: 3 $ */
/* $Date: 10/29/07 8:15a $ */
/* $Log: /NEW SOURCESAFE DATABASE/SDK/PLX/gsc/hpdi32/sbtest/main.c $
 * 
 * 3     10/29/07 8:15a Dnewbold
 * Updated for Linux port.
 * 
 * 2     10/16/06 5:40p Dnewbold
 * Added host os identification.
 * 
 * 1     8/22/05 4:14p Dnewbold
*/

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#include "main.h"
#include "util_close.h"
#include "util_count.h"
#include "util_host.h"
#include "util_id.h"
#include "util_issues.h"
#include "util_label.h"
#include "util_open.h"
#include "util_select.h"
#include "util_status.h"



/* variables	*************************************************************/

		long	rx_size			= 0;
		long	tx_size			= 0;

static	int		_continuous		= 0;
static	int		_def_board		= -1;
static	int		_ignore_errors	= 0;
static	long	_minute_limit	= 0;
static	int		_quit			= 0;
static	int		_test_limit		= -1;



/*****************************************************************************
*
*	Function:	_parse_args
*
*	Purpose:
*
*		Parse the command line arguments.
*
*	Arguments:
*
*		dev		The handle of the board to access.
*
*	Returned:
*
*		None.
*
*****************************************************************************/

static void _parse_args(int argc, char** argv)
{
	char	c;
	int		i;
	int		j;
	int		k;

	printf("USAGE: sbtest <-c> <-C> <-m#> <-n#> <#>\n");
	printf("   -c   Continuous testing, but stop on first error.\n");
	printf("   -C   Continuous testing, disregard errors.\n");
	printf("   -m#  Run for at most # minutes (a decimal number).\n");
	printf("   -n#  Repeat test at most # times (a decimal number).\n");
	printf("   #    The index of the board to test.\n");
	printf(" NOTE:  Hit Ctrl-C to abort continuous testing.\n");

	for (i = 1; i < argc; i++)
	{
		if (strcmp(argv[i], "-c") == 0)
		{
			_continuous	= 1;
			_ignore_errors	= 0;
			continue;
		}

		if (strcmp(argv[i], "-C") == 0)
		{
			_continuous	= 1;
			_ignore_errors	= 1;
			continue;
		}

		if ((argv[i][0] == '-') && (argv[i][1] == 'm') && (argv[i][2]))
		{
			j	= sscanf(&argv[i][2], "%d%c", &k, &c);

			if ((j == 1) && (k > 0))
			{
				_minute_limit	= k;
				continue;
			}

			_quit	= 1;
			printf("ERROR: invalid '-m' argument: %s\n", argv[i]);
			break;
		}

		if ((argv[i][0] == '-') && (argv[i][1] == 'n') && (argv[i][2]))
		{
			j	= sscanf(&argv[i][2], "%d%c", &k, &c);

			if ((j == 1) && (k > 0))
			{
				_test_limit	= k;
				continue;
			}

			_quit	= 1;
			printf("ERROR: invalid '-n' argument: %s\n", argv[i]);
			break;
		}

		if (isdigit(argv[i][0]) == 0)
		{
			_quit	= 1;
			printf("ERROR: invalid 'device' arguments: %s\n", argv[i]);
			break;
		}

		j	= sscanf(argv[i], "%d%c", &k, &c);

		if ((j == 1) && (k >= 0))
		{
			_def_board	= k;
			continue;
		}

		_quit	= 1;
		printf("ERROR: invalid 'device' argument: %s\n", argv[i]);
		break;

	}
}



/*****************************************************************************
*
*	Function:	_perform_tests
*
*	Purpose:
*
*		Perform the appropriate testing.
*
*	Arguments:
*
*		dev		The handle of the board to access.
*
*		index	The index of the above board.
*
*	Returned:
*
*		>= 0	The number of errors seen.
*
*****************************************************************************/

static int _perform_tests(void* dev, int index)
{
	int			errs	= 0;
	char*		psz;
	struct tm*	stm;
	time_t		tt;

	time(&tt);
	stm	= localtime(&tt);
	psz	= asctime(stm);
	label_text("Performing Tests");
	printf("%s", psz);

	id_host();

	errs	+= id_software(dev, VERSION);
	errs	+= id_hardware(dev, index);

	errs	+= operation_issues(dev, &tx_size, &rx_size);
	errs	+= reg_read_test(dev);
	errs	+= reg_write_test(dev);
	errs	+= cable_config_tests(dev);
	errs	+= fifo_config_tests(dev);
	errs	+= io_config_tests(dev);
	errs	+= irq_config_tests(dev);
	errs	+= misc_config_tests(dev);
	errs	+= rx_config_tests(dev);
	errs	+= tx_config_tests(dev);
	errs	+= io_notify_tests(dev);
	errs	+= irq_notify_tests(dev);
	errs	+= io_data_size_io_tests(dev);
	errs	+= special_tests(dev);

	return(errs);
}



/*****************************************************************************
*
*	Function:	main
*
*	Purpose:
*
*		Program entry point.
*
*	Arguments:
*
*		argc			The number of command line arguments.
*
*		argv			The list of command line arguments.
*
*	Returned:
*
*		EXIT_SUCCESS	No errors were seen.
*		EXIT_FAILURE	Errors were seen.
*
*****************************************************************************/

int main(int argc, char** argv)
{
	void*	dev;
	int		errs		= 0;
	time_t	exec		= time(NULL);
	long	failures	= 0;
	long	hours;
	long	mins;
	time_t	now;
	long	passes		= 0;
	int		qty;
	long	secs;
	time_t	test;
	long	tests		= 0;
	time_t	t_limit;

	for (;;)
	{
		test	= time(NULL);
		label_init(29);
		_parse_args(argc, argv);

		if (_quit)
			break;

		printf("\n");
		t_limit	= exec + (_minute_limit * 60);
		errs	= dev_api_status();

		if (errs == 0)
		{
			qty	= dev_board_count();
			errs	= select_1_board(qty, &_def_board);
		}

		if (errs == 0)
		{
			label_text("Testing Board Index");
			printf("%d\n", _def_board);
			errs	= dev_open((U8) _def_board, &dev);
		}

		if (errs == 0)
		{
			errs	= _perform_tests(dev, _def_board);
			errs	+= dev_close((U8) _def_board, dev);
		}

		now	= time(NULL);
		tests++;

		if (errs)
		{
			failures++;
			printf("\nRESULTS: FAIL <---");
		}
		else
		{
			passes++;
			printf("\nRESULTS: PASS");
		}

		secs	= now - test;
		hours	= secs / 3600;
		secs	= secs % 3600;
		mins	= secs / 60;
		secs	= secs % 60;
		printf(" (duration %ld:%ld:%02ld)\n", hours, mins, secs);

		secs	= now - exec;
		hours	= secs / 3600;
		secs	= secs % 3600;
		mins	= secs / 60;
		secs	= secs % 60;
		printf(	"SUMMARY: tests %ld, pass %ld, fail %ld"
				" (duration %ld:%ld:%02ld)\n\n",
				tests,
				passes,
				failures,
				hours,
				mins,
				secs);

		if ((_test_limit > 0) && (_test_limit <= tests))
			break;

		if (_continuous == 0)
			break;

		if ((_ignore_errors == 0) && (errs))
			break;

		if ((_minute_limit) && (now >= t_limit))
			break;
	}

	errs	= errs ? EXIT_FAILURE : EXIT_SUCCESS;
	return(errs);
}


