/*
 * y1564.c
 *
 *  Created on: 29 Sep 2015
 *      Author: Niall.Donovan
 */

#include <api_oam_sdk/performance_monitoring/src/pm_config.h>
#include <api_oam_sdk/service_activation/inc/y1564.h>
#include <api_oam_sdk/service_activation/src/service_activation_types.h>
#include <string.h>



extern y1564Cfg_t		saY1564Cfg;
extern y1564Results_t	saY1564Results;
testStatus_t 			y1564Status = test_disabled;

/**
 * @brief Configure the device to run the RFC2544 tests
 *
 */
int y1564Configure(y1564Cfg_t *y1564Cfg)
{
	uint8_t k;
	uint16_t perfFrameSize = 0;

	if (y1564Cfg != NULL)
	{
		// Validate the frame size on all enabled services
		for (k=0; k<MAX_NUM_SA_SERVICES; k++)
		{
			if (y1564Cfg->serviceCfg[k].enable && (y1564Cfg->serviceCfg[k].frameSize < 64 ||  y1564Cfg->serviceCfg[k].frameSize > MAX_PM_PKT_SIZE ))
			{
				return(-1);
			}

			perfFrameSize = (y1564Cfg->serviceCfg[k].emix[0] * 0x100) + y1564Cfg->serviceCfg[k].emix[1];
			if (y1564Cfg->enPerformanceTest && (perfFrameSize < 64 || perfFrameSize > MAX_PM_PKT_SIZE)) {
				return (-1);
			}

		}
		return( y1564UpdateConfig(y1564Cfg));
	}
	return(1);		// Rejected because NULL pointer provided
}

/**
 * @brief Start the RFC2544 tests using the current configuration
 */
int y1564Start(void)
{
	int		retVal;
	bool	anySvcEn;
	uint8_t	svc;

#if 0
	if (0)
	{
		return(1);			// Operation rejected because the port selected is down.
	}
#endif

	// Check if any y1564 test is enabled...
	anySvcEn = false;
	for (svc = 0; svc < MAX_NUM_SA_SERVICES; svc++)
	{
		if(saY1564Cfg.serviceCfg[svc].enable)
		{
			anySvcEn = true;
			break;
		}
	}
	if (!((saY1564Cfg.enPerformanceTest || saY1564Cfg.enConfigTest) && anySvcEn) )
	{
		return(2);			// Operation rejected because no tests are selected to run.
	}
	y1564Status = test_running;

	retVal = y1564RunTests();
	if (retVal == 1)
	{
		return(3);			// Operation rejected because another Service activation test is already running
	}
	return(4);				// Operation successful
}

/**
 * @brief Stop the current RFC2544 test
 */
int y1564Stop(void)
{
	int	retVal;

	retVal = saStopTest();
	y1564Status = test_stopped;

	return(retVal);
}

/**
 * @brief Read the status and results for the RFC2544 tests.
 */
int y1564Read(testStatus_t *testStatus, y1564Cfg_t *y1564Cfg, uint8_t serviceIndex, testSel_t testSel, y1564SelResults_t *y1564SelResults)
{
	if (serviceIndex >= MAX_NUM_SA_SERVICES)
	{
		return(1);
	}

	if (testSel > sel_performance)
	{
		return(2);
	}

	if (y1564Cfg != NULL)
	{
		memcpy(y1564Cfg, &saY1564Cfg, sizeof(y1564Cfg_t));
	}

	if (y1564SelResults != NULL)
	{
		if (testSel == sel_configuration)
		{
			LOCK_SA_READ(0);
			memcpy(&y1564SelResults->configurationResults, &saY1564Results.configurationResults[serviceIndex], sizeof(configurationResults_t));
			UNLOCK_SA_READ();
		}
		else if (testSel == sel_performance)
		{
			LOCK_SA_READ(0);
			memcpy(&y1564SelResults->performanceResults, &saY1564Results.performanceResults, sizeof(performanceResults_t));
			UNLOCK_SA_READ();
		}
	}

	if (testStatus != NULL)
	{
		*testStatus = y1564Status;
	}

	return(3);
}
