/*! \file 
**********************************************************************************
*Title:                         Discretix Secured Clock Toolkit ATP Test source file
*
* Filename:                    TLK_SCLK_ATP_Service_Clk_Gen_And_Service_Clk_Read.c
*
* 
* Created:                      30.10.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 "MW_ATP_defines.h"


/*****************************************************************************
* Function Name:
*  TST_ATP_TLK_SCLK_ServiceClkGenAndServiceClkRead.
* 
* Inputs:
*  None
*
* Outputs:
*  DxError_t - Function error return
*
* Description:
*    Test the generation of a new service clock. 
*    Using TLK_SCLK_ServiceClkGen and TLK_SCLK_ServiceClkRead. 
*    Those functions generate a new descriptor for secured service clock ,
*    then read it to verify integrity.
*  
* Algorithm:
* 1.	Load parameters and call TLK_SCLK_ServiceClkGen –generate a new descriptor for secured service clock.
* 2.	Call TLK_SCLK_MCServiceClkRevalidate with the new time.
* 3.	Call TLK_SCLK_ServiceClkRead using the descriptor and NULL application ID
*     (the time format is TLK_SCLK_SECONDS_SINCE_FORMAT). 
* 4.	validate that the service clock descriptor is as expected:
*      a.	Compare the service clock status with the expected status.
*      b.	Get the system time and compare it to the returned service clock time
*******************************************************************************/

DxError_t TST_ATP_TLK_SCLK_ServiceClkGenAndServiceClkRead(void)
{
   DxError_t                            TST_Status;
   DxError_t                            TST_TestStatus;
   TLK_SCLK_ServiceClockDescriptor_t    TST_ServiceDes;
   TLK_SCLK_ServiceClockTime_t          TST_ServiceCurrentTime;
   TLK_SCLK_ReadStatus_t                TST_ServiceStatus;
   TLK_SCLK_ServiceClockTime_t          TST_SystemTime;
   TLK_SCLK_ServiceClockTime_t          TST_ServiceNewTime;
   DxUint32_t                           Offset = 0;
   DxTime_t                             TST_SystemTimeInSeconds;
   DxTime_t                             TST_ServiceCurrentTimeInSeconds;
   TLK_SCLK_TimeFormat_t                TST_gTimeFormat;
   DxUint8_t                            TST_gNumberOfTimeFormat = 2;
   DxTime_t                             TST_gmaxAllowedDriftIn0_1Seconds = 0x150;
   DxTime_t                             TST_gmaximumRevalidationPeriod = 10;

#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," ** TST_ATP_TLK_SCLK_ServiceClkGenAndServiceClkRead Test    \n"));     
   ATP_LOG_TST_PRINT((MW_ATP_MSG," ****************************************************** \n \n"));


    /* 1.	Load parameters and call TLK_SCLK_ServiceClkGen.*/
  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",
                                                 "TST_ATP_TLK_SCLK_ServiceClkGenAndServiceClkRead","");



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

  MW_TST_Util_GetTime(&TST_ServiceNewTime.secondsSinceFormat);
#ifdef SCLK_ON_SEP
  TST_SystemTimeInSeconds = TST_ServiceNewTime.secondsSinceFormat;
#else
  TST_SystemTimeInSeconds = DX_VOS_GetTime();
  TST_ServiceNewTime.secondsSinceFormat = TST_SystemTimeInSeconds;
#endif


  TST_Status = TLK_SCLK_ServiceClkRevalidate(&TST_ServiceDes,
                                            DX_NULL,
                                            &TST_ServiceNewTime,
                                            TST_gTimeFormat,
                                            "PWD",3,
                                            TST_gWorkSpace,
                                            TST_gWorkSpaceSizeInBytes);

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



 /*3.	Call TLK_SCLK_ServiceClkRead using the descriptor and NULL application ID .*/
  for (TST_gTimeFormat=0; TST_gTimeFormat< TST_gNumberOfTimeFormat;TST_gTimeFormat++)
  {
   

    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",
                                                   "TST_ATP_TLK_SCLK_ServiceClkGenAndServiceClkRead","");


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

    if (TST_ServiceStatus != TLK_SCLK_STATUS_VALID)
    {

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

    }

    /* b.	Get the system time and compare it to the returned service clock time */

   if (TST_gTimeFormat == TLK_SCLK_SECONDS_SINCE_FORMAT)
    {
      TST_Status = TLK_SCLK_TST_GetFormattedTime(TST_gTimeFormat,
                                                Offset,
                                                &TST_SystemTime);

     TST_ATP_CHECK_ERROR_RETURN(TST_Status,"TLK_SCLK_TST_GetFormattedTime",
                                                     "TST_ATP_TLK_SCLK_ServiceClkGenAndServiceClkRead","");

      /*validate  the pulse a delta of one second*/
      if (TST_SystemTime.secondsSinceFormat >= TST_ServiceCurrentTime.secondsSinceFormat+2)
      {
        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 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;
      }

      /*compare between the converted time values*/
      if (TST_SystemTimeInSeconds >= TST_ServiceCurrentTimeInSeconds + 3)
      {
        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," ** TST_ATP_TLK_SCLK_ServiceClkGenAndServiceClkRead  Test  PASS !!! \n"));     
  ATP_LOG_TST_PRINT((MW_ATP_MSG," ************************************************************** \n \n"));

  return TST_PASS;
  EXIT_ON_ERROR:
  {
    return DX_FAILURE;
  }

}
