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

/************* Include Files ***********************************/
#include "tlk_sclk_api.h"
#include "TLK_SCLK_ATP_Defines.h"
#include "TLK_SCLK_ATP_data.h" 
#include "TLK_SCLK_ATP_tests.h"
#include "tlk_sclk_api_types.h"
#include "MW_ATP_UTIL_funcs.h"
#include "TLK_SCLK_TST_UTIL.h"
#include "DX_VOS_Thread.h"


/*****************************************************************************
* Function Name:
*  TLK_SCLK_ATP_Master_Clk_Update.
* 
* Inputs:
*  None
*
* Outputs:
*  DxError_t - Function error return
*
* Description:
*   To test the periodic update of the master clock by creating a service 
*   clock descriptor. Using the Secure Time Toolkit API TLK_SCLK_ServiceClkRead
*   and Secure Time Toolkit API TLK_SCLK_ServiceClkGen.
*  
* 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 for the master clock to update.
* 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 new time with the returned service clock time
*******************************************************************************/

DxError_t TLK_SCLK_ATP_Master_Clk_Update(void)
{
  DxError_t                            TST_Status;
  DxError_t                            TST_TestStatus;
  TLK_SCLK_ServiceClockDescriptor_t    TST_ServiceDes;
  TLK_SCLK_ServiceClockTime_t          TST_ServiceCurrentTime;
  TLK_SCLK_ServiceClockTime_t          TST_ServiceTime;
  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 = 0x150;
  DxTime_t                             TST_gmaximumRevalidationPeriod = 10;
  DxChar_t                             TestName[] = "TLK_SCLK_ATP_Master_Clk_Update";
#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_Master_Clk_Update 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_Status = TLK_SCLK_ServiceClkGen(&TST_ServiceDes,
                                     DX_NULL,
                                     TST_gmaxAllowedDriftIn0_1Seconds,
                                     TST_gmaximumRevalidationPeriod,
                                     TLK_SCLK_WORLD_READABLE,
                                     "PWD",3,
                                     TST_gWorkSpace,
                                     TST_gWorkSpaceSizeInBytes);

  TST_ATP_CHECK_ERROR_RETURN(TST_Status,"TLK_SCLK_ServiceClkGen",
                            "TLK_SCLK_ATP_Master_Clk_Update",TestName);


  /* 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_Status = TLK_SCLK_ServiceClkRevalidate(&TST_ServiceDes,
                                            DX_NULL,
                                            &TST_ServiceTime,
                                            TST_gTimeFormat,
                                            "PWD",3,
                                            TST_gWorkSpace,
                                            TST_gWorkSpaceSizeInBytes);

  TST_ATP_CHECK_ERROR_RETURN(TST_Status,"TLK_SCLK_ServiceClkRevalidate",
                             "TST_ATP_TLK_SCLK_ServiceClkRevalidation",TestName);


  for (TST_gTimeFormat=0; TST_gTimeFormat< TST_gNumberOfTimeFormat;TST_gTimeFormat++)
  {
    /*3.	Call TLK_SCLK_ServiceClkRead - read the current time from the service secured clock descriptor.*/

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

    TST_ATP_CHECK_ERROR_RETURN(TST_Status,"TLK_SCLK_ServiceClkRead",
                              "TLK_SCLK_ATP_Master_Clk_Update",TestName);

    /* 4.	Wait the required time for the master clock to update.*/
    
	#ifdef SUPPORT_SLEEP
		DX_VOS_Sleep (TLK_SCLK_MC_PARAM_UPDATE_PERIOD_IN_SEC_DEFAULT*100);
	#endif

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

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

    TST_ATP_CHECK_ERROR_RETURN(TST_Status,"TLK_SCLK_ServiceClkRead",
                              "TLK_SCLK_ATP_Master_Clk_Update",TestName);

    /* 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_VALID)
    {

      ATP_LOG_TST_PRINT((MW_ATP_MSG,"\n!!!! TST_Status - TLK_SCLK_ATP_Service_Clk_Revalidate_And_Master_Clk_Revalidate\n"));
      ATP_LOG_TST_PRINT((MW_ATP_MSG,"!!!! TST_Status - 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 >= TST_ServiceTime.secondsSinceFormat+TLK_SCLK_TST_ALLOWED_DRIFT_LIMIT)
      {
        ATP_LOG_TST_PRINT((MW_ATP_MSG,"\n!!!! TST_Status - TST_ATP_TLK_SCLK_ServiceClkRevalidation\n"));
        ATP_LOG_TST_PRINT((MW_ATP_MSG,"!!!! TST_Status - 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_Status = DX_VOS_GenTimeToSecs(&(TST_ServiceCurrentTime.dateTimeFormat),&(TST_ServiceCurrentTimeInSeconds));
        if (TST_Status != DX_SUCCESS)
        {
          ATP_LOG_TST_PRINT((MW_ATP_MSG,"\n!!!! TST_Status - TST_ATP_TLK_SCLK_ServiceClkRevalidation\n"));
          ATP_LOG_TST_PRINT((MW_ATP_MSG,"!!!! TST_Status - Service Current Time Convert Failed\n"));
          return TST_FAIL;
        }

         /*Converts Generalized service time to number of seconds */
        TST_Status = DX_VOS_GenTimeToSecs(&(TST_ServiceTime.dateTimeFormat),&(TST_ServiceTimeInSeconds));
        if (TST_Status != DX_SUCCESS)
        {
          ATP_LOG_TST_PRINT((MW_ATP_MSG,"\n!!!! TST_Status - TST_ATP_TLK_SCLK_ServiceClkRevalidation\n"));
          ATP_LOG_TST_PRINT((MW_ATP_MSG,"!!!! TST_Status - Service Time Convert Failed\n"));
          return TST_FAIL;
        }
        
        /*compare between the converted time values*/
        if (TST_ServiceCurrentTimeInSeconds >= TST_ServiceTimeInSeconds+TLK_SCLK_TST_ALLOWED_DRIFT_LIMIT)
        {
          ATP_LOG_TST_PRINT((MW_ATP_MSG,"\n!!!! TST_Status - TST_ATP_TLK_SCLK_ServiceClkRevalidation\n"));
          ATP_LOG_TST_PRINT((MW_ATP_MSG,"!!!! TST_Status - 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_Master_Clk_Update  Test  PASS !!! \n"));     
  ATP_LOG_TST_PRINT((MW_ATP_MSG," ************************************************************** \n \n"));

  return TST_PASS;
  EXIT_ON_ERROR:
  {
    return DX_FAILURE;
  }

}
