/*!
 * In Samsung Ukraine R&D Center (SRK) under a contract between
 * LLC "Samsung Electronics Ukraine Company" (Kyiv, Ukraine)
 * and "Samsung Electronics Co", Ltd (Seoul, Republic of Korea)
 * Copyright: (c) Samsung Electronics Co, Ltd 2019. All rights reserved.
 */


#include <stdint.h>
#include <stddef.h>
#include <string.h>

#ifdef USE_MOBICORE
#include "tlStd.h"
#include "TlApi/TlApi.h"
#include "TlApi/TlApiMcSystem.h"
#endif

#ifdef USE_QSEE
#include <qsee_timer.h>
#include "qsee_heap.h"
#endif

#ifdef USE_BLOWFISH
#include <time.h>
#include <tee_internal_api.h>
#endif

#ifdef USE_TRUSTY_UNISOC
#include <tee_api.h>
struct timespec {
    long tv_sec;        /* seconds */
    long tv_nsec;       /* nanoseconds */
};
#endif

#include "tz_utils.h"
#include "tz_debug.h"

void sleepProcess(int timeoutTimeInMilli)
{
#ifdef USE_MOBICORE
    timestamp_t startTime;
    timestamp_t currentTime;
    timestamp_t timeoutTime = timeoutTimeInMilli * 1000;

    tlApiGetSecureTimestamp(&startTime);
	do {
		tlApiGetSecureTimestamp (&currentTime);
	} while((startTime != 0) &&((currentTime-startTime) < timeoutTime));
#endif
#ifdef USE_QSEE
    unsigned long long startTime;
    unsigned long long timeoutTime = timeoutTimeInMilli;

    startTime = qsee_get_uptime();
    while (qsee_get_uptime() - startTime <= timeoutTime){}
#endif
#if defined(USE_BLOWFISH)
    struct timespec req;

    req.tv_sec = 0;
    req.tv_nsec = 1000000 * timeoutTimeInMilli;
    nanosleep(&req, NULL);
#endif
#if defined(USE_TRUSTY_UNISOC)
    TEE_Time startTime, endTime;
    TEE_GetSystemTime(&startTime);
    //LOGI("start sec : %u, start milli : %u", startTime.seconds, startTime.millis);
    TEE_GetSystemTime(&endTime);
    //LOGI("end sec : %u, end milli : %u", endTime.seconds, endTime.millis);
    while (endTime.millis - startTime.millis <= timeoutTimeInMilli){
        TEE_GetSystemTime(&endTime);
    }
    //LOGI("end sec : %u, end milli : %u", endTime.seconds, endTime.millis);
#endif

}

void * tz_malloc(uint32_t size)
{
#ifdef USE_MOBICORE
    return tlApiMalloc(size, 0);
#endif
#ifdef USE_QSEE
    return qsee_malloc(size);
#endif
#if defined(USE_BLOWFISH) || defined(USE_TRUSTY_UNISOC)
    return TEE_Malloc(size, 0);
#endif
}

void tz_free(void * data)
{
#ifdef USE_MOBICORE
    tlApiFree(data);
#endif
#ifdef USE_QSEE
    qsee_free(data);
#endif
#if defined(USE_BLOWFISH) || defined(USE_TRUSTY_UNISOC)
    TEE_Free(data);
#endif
    data = NULL;
}

void secure_memclear( void * secure_data, size_t size )
{
    volatile uint8_t * temp = secure_data;

    if ( (NULL == secure_data) || (0 == size) || (SIZE_MAX < size) )
    {
        LOGE("incorrect input parameters");
        return;
    }

    while ( size-- )
    {
        *temp++ = 0;
    }
}

