/*! \file 
**********************************************************************************
*Title:                         Discretix Secured Clock Toolkit ATP Test source file
*
* Filename:                    TLK_SCLK_ATP_Service_Clk_Revalidate.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"


/*****************************************************************************
* Function Name:
*  TST_ATP_TLK_SCLK_ServiceClkRevalidation.
* 
* Inputs:
*  None
*
* Outputs:
*  DxError_t - Function error return
*
* Description:
*    Test the revalidation of the service clock alone. 
*    Using Time Toolkit API TLK_SCLK_ServiceClkGen to generate a new descriptor
*    for secured service clock,  then call the Time Toolkit API 
*    TLK_SCLK_MCServiceClkRevalidate with new time (in the master clock offset limit). 
*  
* Algorithm:
* 1.	Load parameters and call TLK_SCLK_ServiceClkGen –generate a 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.	Initialize new time (by adding 100 seconds to the service current time  received from the previous operation).
* 5.	Call TLK_SCLK_MCServiceClkRevalidate with the new time. 
* 6.	Call TLK_SCLK_ServiceClkRead using the descriptor and the application ID received from the previous operation.
* 7.	validate that the service clock descriptors 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 TST_ATP_TLK_SCLK_ServiceClkRevalidation(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_ServiceNewTime;
  TLK_SCLK_ReadStatus_t                TST_ServiceStatus;
  DxTime_t                             TST_ServiceCurrentTimeInSeconds;
  DxTime_t                             TST_ServiceNewTimeInSeconds;
  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;
  DxTime_t                 TST_SystemTimeInSeconds;
#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_ServiceClkRevalidation 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_ServiceClkRevalidation","");


  /* 2.  Call TLK_SCLK_MCServiceClkRevalidate with the system time.*/
  MW_TST_Util_GetTime(&TST_ServiceNewTime.secondsSinceFormat);
#ifdef SCLK_ON_SEP
  TST_SystemTimeInSeconds = TST_ServiceNewTime.secondsSinceFormat;
  TST_ServiceNewTime.secondsSinceFormat = TST_SystemTimeInSeconds + 0x100;
#else
 TST_ServiceNewTime.secondsSinceFormat += 0x100;
#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","");


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

    /* 4.	Initialize new time (by adding 100 seconds to the service current time  received from the previous operation).*/

    if (TST_gTimeFormat == TLK_SCLK_SECONDS_SINCE_FORMAT)
      TST_ServiceNewTime.secondsSinceFormat = TST_ServiceCurrentTime.secondsSinceFormat + 100;
    else
    {
      TST_ServiceNewTime.dateTimeFormat = TST_ServiceCurrentTime.dateTimeFormat;
      if(TST_ServiceNewTime.dateTimeFormat.year_l2 == '9')
      {
        TST_ServiceNewTime.dateTimeFormat.year_l2 = '0';
        if(TST_ServiceNewTime.dateTimeFormat.year_m2 == '9')
        {
          TST_ServiceNewTime.dateTimeFormat.year_m2 = '0';
          if(TST_ServiceNewTime.dateTimeFormat.year_l1 == '9')
          {
            TST_ServiceNewTime.dateTimeFormat.year_l1 = '0';
            TST_ServiceNewTime.dateTimeFormat.year_m1 += 1;
          }
          else
          {
            TST_ServiceNewTime.dateTimeFormat.year_l1 += 1;
          }
        }
        else
        {
          TST_ServiceNewTime.dateTimeFormat.year_m2 += 1;
        }
      }
      else
      {
        TST_ServiceNewTime.dateTimeFormat.year_l2+=1;
      }
    }

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

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

    /* 6.	Call TLK_SCLK_ServiceClkRead using the descriptor and the application ID received from the previous operation.*/

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


    /* 7.	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 - TST_ATP_TLK_SCLK_ServiceClkRevalidation\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_ServiceNewTime.secondsSinceFormat >= TST_ServiceCurrentTime.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 system time to number of seconds */
      TST_Status = DX_VOS_GenTimeToSecs(&(TST_ServiceNewTime.dateTimeFormat),&(TST_ServiceNewTimeInSeconds));
      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 - System Time Convert Failed\n"));
        return TST_FAIL;
      }

      /*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_ServiceNewTimeInSeconds >= TST_ServiceCurrentTimeInSeconds+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," ** TST_ATP_TLK_SCLK_ServiceClkRevalidation  Test  PASS !!! \n"));     
  ATP_LOG_TST_PRINT((MW_ATP_MSG," ************************************************************** \n \n"));

  return TST_PASS;
  EXIT_ON_ERROR:
  {
    return DX_FAILURE;
  }
}
