/*! \file 
**********************************************************************************
*Title:                         Discretix Secured Clock Toolkit ATP Test source file
*
* Filename:                    TLK_SCLK_ATP_Service_Clk_Validity_Grace_Period.c
*
* 
* Created:                      17.02.2009
*
* 
* \Author                      Liron Dror
*
* \Remarks
*           Copyright (C) 2009 by Discretix Technologies Ltd. All Rights reserved.
**********************************************************************************/

/************* Include Files ***********************************/
#include "DX_VOS_Thread.h"

#include "TLK_SCLK_ATP_Defines.h"
#include "TLK_SCLK_ATP_data.h" 
#include "TLK_SCLK_ATP_tests.h"
#include "TLK_SCLK_TST_UTIL.h"

#include "MW_ATP_UTIL_funcs.h"

#include "tlk_sclk_api.h"
#include "tlk_sclk_api_types.h"
#include "tlk_sclk_api_errors.h"
/*****************************************************************************
* Function Name:
*  TLK_SCLK_ATP_Service_Clk_Validity_Grace_Period.
* 
* Inputs:
*  None
*
* Outputs:
*  DxError_t - Function error return
*
* Description:
*  To test the output parameters of Secure Time Toolkit API's TLK_SCLK_ServiceClkRead
*  when the service descriptor is no longer valid (period expired) and during "grace period".
*  
* Algorithm:
* 1.	Load parameters and call TLK_SCLK_ServiceClkGen –generate new descriptor for secured service clock.
* 2     Call TLK_SCLK_MCServiceClkRevalidate with the system time
* 3.	Call TLK_SCLK_ServiceClkRead  - read the current time from the service secured clock descriptor.
* 4.	Wait the required time until the service descriptor enters its grace period.
* 5.	Call TLK_SCLK_ServiceClkRead  - read the new updated time from the service secured clock descriptor.
* 6.	validate that the service clock descriptor is as expected :
*   a.	Compare the service clock status with the expected.
*   b.	Compare the return time with the expected .
* 7.	Wait the required time until the service descriptor no longer valid.
* 8.	Call TLK_SCLK_ServiceClkRead.
* 9.	validate that the service clock descriptor is as expected :
*   a.	Compare the service clock status with the expected.
*   b.	Compare the return time with the expected .
*******************************************************************************/

DxError_t TLK_SCLK_ATP_Service_Clk_Validity_Grace_Period(void)
{
#ifdef SUPPORT_SLEEP
	DxError_t                            TST_Error;
	DxError_t                            TST_TestStatus;
	TLK_SCLK_ServiceClockDescriptor_t    TST_ServiceDes;
	TLK_SCLK_ServiceClockTime_t          TST_ServiceCurrentTime;
	TLK_SCLK_ServiceClockTime_t          TST_ServiceTime;
	TLK_SCLK_ServiceClockTime_t          TST_CheckTime;
	TLK_SCLK_ReadStatus_t                TST_ServiceStatus;
	DxTime_t                             TST_ServiceCurrentTimeInSeconds;
	DxTime_t                             TST_ServiceTimeInSeconds;
	TLK_SCLK_TimeFormat_t                TST_gTimeFormat;
	DxUint8_t                            TST_gNumberOfTimeFormat = 2;
	DxTime_t                             TST_gmaxAllowedDriftIn0_1Seconds = 0x15;
	DxTime_t                             TST_gmaximumRevalidationPeriod = 10;
	DxTime_t                             TST_time_to_wait; 
#ifdef SCLK_ON_SEP
	DxUint32_t 						    timeAddress;
#endif
	

	TST_gTimeFormat=TLK_SCLK_SECONDS_SINCE_FORMAT;

	ATP_LOG_TST_PRINT((MW_ATP_MSG," **************************************************************** \n"));
	ATP_LOG_TST_PRINT((MW_ATP_MSG," **  TLK_SCLK_ATP_Service_Clk_Validity_Grace_Period Test       **\n"));     
	ATP_LOG_TST_PRINT((MW_ATP_MSG," **************************************************************** \n \n"));


	/* 1.	Load parameters and call TLK_SCLK_ServiceClkGen 
	– generate new descriptor for secured service clock.*/

	TST_Error = TLK_SCLK_ServiceClkGen(&TST_ServiceDes,
										DX_NULL,
										TST_gmaxAllowedDriftIn0_1Seconds,
										TST_gmaximumRevalidationPeriod,
										TLK_SCLK_WORLD_READABLE,
                                        "PWD",3,
										TST_gWorkSpace,
										TST_gWorkSpaceSizeInBytes);

	TST_TestStatus = TLK_SCLK_TST_CheckErrorReturn(TST_Error,"TLK_SCLK_ServiceClkGen",
												   "TLK_SCLK_ATP_Service_Clk_Validity_Grace_Period");

	if (TST_TestStatus != TST_PASS)
		return TST_FAIL;

	/* 2.  Call TLK_SCLK_MCServiceClkRevalidate with the system time.*/

	MW_TST_Util_GetTime(&TST_ServiceTime.secondsSinceFormat);
	#ifndef SCLK_ON_SEP
		TST_ServiceTime.secondsSinceFormat += 0x100;
	#endif

	TST_Error = TLK_SCLK_ServiceClkRevalidate(&TST_ServiceDes,
											  DX_NULL,
											  &TST_ServiceTime,
											  TST_gTimeFormat,
                                              "PWD",3,
											  TST_gWorkSpace,
											  TST_gWorkSpaceSizeInBytes);

	TST_TestStatus = TLK_SCLK_TST_CheckErrorReturn(TST_Error,"TLK_SCLK_ServiceClkRevalidate",
		                                           "TLK_SCLK_ATP_Service_Clk_Validity_Grace_Period");

	if (TST_TestStatus != TST_PASS)
		return TST_FAIL;

	/*3.	Call TLK_SCLK_ServiceClkRead - read the current time from the service secured clock descriptor.*/

		TST_Error = TLK_SCLK_ServiceClkRead(&TST_ServiceDes,
											DX_NULL,
											&TST_ServiceTime,
											TST_gTimeFormat, 
											&TST_ServiceStatus,
                                            "PWD",3,
  											TST_gWorkSpace,
											TST_gWorkSpaceSizeInBytes);

		TST_TestStatus = TLK_SCLK_TST_CheckErrorReturn(TST_Error,"TLK_SCLK_ServiceClkRead",
			                                           "TLK_SCLK_ATP_Service_Clk_Validity_Grace_Period");

		if (TST_TestStatus != TST_PASS)
			return TST_FAIL;

		/* 4.Wait the required time until the service descriptor enters its grace period.*/
        
		MW_TST_Util_GetTime(&TST_CheckTime.secondsSinceFormat);
		#ifndef SCLK_ON_SEP
				TST_CheckTime.secondsSinceFormat += 0x100;
		#endif
				
		TST_time_to_wait = (((TST_ServiceDes.clockValidityLimitInSeconds)-TST_CheckTime.secondsSinceFormat)/100)+TST_gmaxAllowedDriftIn0_1Seconds ;
			                                                                                  
		DX_VOS_Sleep (TST_time_to_wait);

		/* 5.	Call TLK_SCLK_ServiceClkRead - read the new update time from the service secured clock descriptor .*/

		TST_Error = TLK_SCLK_ServiceClkRead(&TST_ServiceDes,
											DX_NULL,
											&TST_ServiceCurrentTime,
											TST_gTimeFormat, 
											&TST_ServiceStatus,
                                            "PWD",3,
											TST_gWorkSpace,
											TST_gWorkSpaceSizeInBytes);

		TST_TestStatus = TLK_SCLK_TST_CheckErrorReturn(TST_Error,"TLK_SCLK_ServiceClkRead",
													   "TLK_SCLK_ATP_Service_Clk_Validity_Grace_Period");

		if (TST_TestStatus != TST_PASS)
			return TST_FAIL;

		/* 6.	validate that the service clock descriptors is as expected:*/
		/*a. Compare the service clock status with the expected.*/

		if (TST_ServiceStatus != TLK_SCLK_STATUS_MUST_REVALIDATE)
		{

			ATP_LOG_TST_PRINT((MW_ATP_MSG,"\n!!!! TST_Error - TLK_SCLK_ATP_Service_Clk_Validity_Grace_Period\n"));
			ATP_LOG_TST_PRINT((MW_ATP_MSG,"!!!! TST_Error - invalidate service clock status in grace period\n"));
			return TST_FAIL;

		}

		/*b. Compare the new time with the returned service clock time.*/
		if (TST_gTimeFormat == TLK_SCLK_SECONDS_SINCE_FORMAT)
		{
			if (TST_ServiceCurrentTime.secondsSinceFormat == 0)
			{
				ATP_LOG_TST_PRINT((MW_ATP_MSG,"\n!!!! TST_Error - TLK_SCLK_ATP_Service_Clk_Validity_Grace_Period\n"));
				ATP_LOG_TST_PRINT((MW_ATP_MSG,"!!!! TST_Error - invalidate service clock current time\n"));
				return TST_FAIL;
			}
		}
		else /* if TST_gTimeFormat == TLK_SCLK_DATE_TIME_FORMAT  */
		{
			/*Converts Generalized service current time to number of seconds */
			TST_Error = DX_VOS_GenTimeToSecs(&(TST_ServiceCurrentTime.dateTimeFormat),&(TST_ServiceCurrentTimeInSeconds));
			if (TST_Error != DX_SUCCESS)
			{
				ATP_LOG_TST_PRINT((MW_ATP_MSG,"\n!!!! TST_Error - TLK_SCLK_ATP_Service_Clk_Validity_Grace_Period\n"));
				ATP_LOG_TST_PRINT((MW_ATP_MSG,"!!!! TST_Error - Service Current Time Convert Failed\n"));
				return TST_FAIL;
			}

			/*Converts Generalized service time to number of seconds */
			TST_Error = DX_VOS_GenTimeToSecs(&(TST_ServiceTime.dateTimeFormat),&(TST_ServiceTimeInSeconds));
			if (TST_Error != DX_SUCCESS)
			{
				ATP_LOG_TST_PRINT((MW_ATP_MSG,"\n!!!! TST_Error - TLK_SCLK_ATP_Service_Clk_Validity_Grace_Period\n"));
				ATP_LOG_TST_PRINT((MW_ATP_MSG,"!!!! TST_Error - Service Time Convert Failed\n"));
				return TST_FAIL;
			}

			/*compare between the converted time values*/
			if (TST_ServiceCurrentTimeInSeconds == 0 )
			{
				ATP_LOG_TST_PRINT((MW_ATP_MSG,"\n!!!! TST_Error - TLK_SCLK_ATP_Service_Clk_Validity_Grace_Period\n"));
				ATP_LOG_TST_PRINT((MW_ATP_MSG,"!!!! TST_Error - invalidate service clock current time\n"));
				return TST_FAIL;
			}

		}

	/* Call TLK_SCLK_MCServiceClkRevalidate with the system time.*/

	MW_TST_Util_GetTime(&TST_ServiceTime.secondsSinceFormat);
	#ifndef SCLK_ON_SEP
		TST_ServiceTime.secondsSinceFormat += 0x100;
	#endif

	TST_Error = TLK_SCLK_ServiceClkRevalidate(&TST_ServiceDes,
											  DX_NULL,
											  &TST_ServiceTime,
											  TST_gTimeFormat,
                                              "PWD",3,
											  TST_gWorkSpace,
											  TST_gWorkSpaceSizeInBytes);

	TST_TestStatus = TLK_SCLK_TST_CheckErrorReturn(TST_Error,"TLK_SCLK_ServiceClkRevalidate",
		                                           "TLK_SCLK_ATP_Service_Clk_Validity_Grace_Period");

	if (TST_TestStatus != TST_PASS)
		return TST_FAIL;

	
	/*.	Call TLK_SCLK_ServiceClkRead - read the current time from the service secured clock descriptor.*/

	TST_Error = TLK_SCLK_ServiceClkRead(&TST_ServiceDes,
										DX_NULL,
										&TST_ServiceTime,
										TST_gTimeFormat, 
										&TST_ServiceStatus,
                                        "PWD",3,
										TST_gWorkSpace,
										TST_gWorkSpaceSizeInBytes);

	TST_TestStatus = TLK_SCLK_TST_CheckErrorReturn(TST_Error,"TLK_SCLK_ServiceClkRead",
			                                       "TLK_SCLK_ATP_Service_Clk_Validity_Grace_Period");

	if (TST_TestStatus != TST_PASS)
			return TST_FAIL;

	/* 7.	Wait the required time until the service descriptor no longer valid.*/
	MW_TST_Util_GetTime(&TST_CheckTime.secondsSinceFormat);
	#ifndef SCLK_ON_SEP
			TST_CheckTime.secondsSinceFormat += 0x100;
	#endif
	TST_time_to_wait = (((TST_ServiceDes.clockValidityLimitInSeconds)-TST_CheckTime.secondsSinceFormat)/100)+TST_gmaxAllowedDriftIn0_1Seconds ;
	
	DX_VOS_Sleep (TST_gmaximumRevalidationPeriod+(TST_time_to_wait)*100+1000);

	/* 8.	Call TLK_SCLK_ServiceClkRead - read the new update time from the service secured clock descriptor .*/

	TST_Error = TLK_SCLK_ServiceClkRead(&TST_ServiceDes,
										DX_NULL,
										&TST_ServiceCurrentTime,
										TST_gTimeFormat, 
										&TST_ServiceStatus,
                                        "PWD",3,
 										TST_gWorkSpace,
										TST_gWorkSpaceSizeInBytes);

	if (TST_Error != TLK_SCLK_RC_ERROR_API_SECURE_CLOCK_EXPIRED)
	{
		TST_TestStatus = TLK_SCLK_TST_CheckErrorReturn(TST_Error,"TLK_SCLK_ServiceClkRead",
			"TLK_SCLK_ATP_Service_Clk_Validity_Grace_Period");

		if (TST_TestStatus != TST_PASS)
			return TST_FAIL;
	}
	
	else
	{
		ATP_LOG_TST_PRINT((MW_ATP_MSG,"TST_message - "));
		ATP_LOG_TST_PRINT((MW_ATP_MSG,"TLK_SCLK_ServiceClkRead"));
		ATP_LOG_TST_PRINT((MW_ATP_MSG," pass \n"));                                       
		TST_TestStatus=TST_PASS;
	}

	if (TST_TestStatus != TST_PASS)
		return TST_FAIL;
	

	/* 9.	validate that the service clock descriptors is as expected:*/
	/*a. Compare the service clock status with the expected.*/
	if (TST_ServiceStatus != TLK_SCLK_STATUS_UNSET_INVALID)
		{

			ATP_LOG_TST_PRINT((MW_ATP_MSG,"\n!!!! TST_Error - TLK_SCLK_ATP_Service_Clk_Validity_Grace_Period\n"));
			ATP_LOG_TST_PRINT((MW_ATP_MSG,"!!!! TST_Error - invalidate service clock status\n"));
			return TST_FAIL;

		}


		/*b. Compare the new time with the returned service clock time.*/
		if (TST_gTimeFormat == TLK_SCLK_SECONDS_SINCE_FORMAT)
		{
			if (TST_ServiceCurrentTime.secondsSinceFormat != 0)
			{
				ATP_LOG_TST_PRINT((MW_ATP_MSG,"\n!!!! TST_Error - TLK_SCLK_ATP_Service_Clk_Validity_Grace_Period\n"));
				ATP_LOG_TST_PRINT((MW_ATP_MSG,"!!!! TST_Error - invalidate service clock current time\n"));
				return TST_FAIL;
			}
		}
		else /* if TST_gTimeFormat == TLK_SCLK_DATE_TIME_FORMAT  */
		{
			/*Converts Generalized service current time to number of seconds */
			TST_Error = DX_VOS_GenTimeToSecs(&(TST_ServiceCurrentTime.dateTimeFormat),&(TST_ServiceCurrentTimeInSeconds));
			if (TST_Error != DX_SUCCESS)
			{
				ATP_LOG_TST_PRINT((MW_ATP_MSG,"\n!!!! TST_Error - TLK_SCLK_ATP_Service_Clk_Validity_Grace_Period\n"));
				ATP_LOG_TST_PRINT((MW_ATP_MSG,"!!!! TST_Error - Service Current Time Convert Failed\n"));
				return TST_FAIL;
			}

			/*Converts Generalized service time to number of seconds */
			TST_Error = DX_VOS_GenTimeToSecs(&(TST_ServiceTime.dateTimeFormat),&(TST_ServiceTimeInSeconds));
			if (TST_Error != DX_SUCCESS)
			{
				ATP_LOG_TST_PRINT((MW_ATP_MSG,"\n!!!! TST_Error - TLK_SCLK_ATP_Service_Clk_Validity_Grace_Period\n"));
				ATP_LOG_TST_PRINT((MW_ATP_MSG,"!!!! TST_Error - Service Time Convert Failed\n"));
				return TST_FAIL;
			}

			/*compare between the converted time values*/
			if (TST_ServiceCurrentTimeInSeconds != 0 )
			{
				ATP_LOG_TST_PRINT((MW_ATP_MSG,"\n!!!! TST_Error - TLK_SCLK_ATP_Service_Clk_Validity_Grace_Period\n"));
				ATP_LOG_TST_PRINT((MW_ATP_MSG,"!!!! TST_Error - invalidate service clock current time\n"));
				return TST_FAIL;
			}

		}
	ATP_LOG_TST_PRINT((MW_ATP_MSG," **************************************************************\n\n"));
	ATP_LOG_TST_PRINT((MW_ATP_MSG," ** TLK_SCLK_ATP_Service_Clk_Validity_Grace_Period  Test  PASS !!! \n"));     
	ATP_LOG_TST_PRINT((MW_ATP_MSG," ************************************************************** \n \n"));

	return TST_PASS;

#endif

}
