/*
* Copyright (c) 2013 TRUSTONIC LIMITED
* All rights reserved
*
* The present software is the confidential and proprietary information of
* TRUSTONIC LIMITED. You shall not disclose the present software and shall
* use it only in accordance with the terms of the license agreement you
* entered into with TRUSTONIC LIMITED. This software may be subject to
* export or import laws in certain countries.
*/
#include "tlStd.h"
#include "TlApi/TlApi.h"

#include "tz_platform.h"
#include "cmd_handler.h"

#include "stack_protection.h"

#define SEMTA_VER "2016.06.15.1"

#ifdef DEBUG_LOW
DECLARE_TRUSTLET_MAIN_STACK(250000)
#else
DECLARE_TRUSTLET_MAIN_STACK(300000)
#endif

#if defined USE_SCRYPTO || USE_TBASE_API_LEVEL_11
void __use_no_semihosting(void){}
#else
DECLARE_TRUSTLET_MAIN_HEAP(300000)
#endif

#ifdef USE_SCRYPTO
char TZ_APP_NAME[] = { "sem" };
#endif

/**
* Trusted Application entry.
*/
_TLAPI_ENTRY void tlMain( const addr_t tciBuffer, const uint32_t tciBufferLen ) {
    cmd_t    cmd_buf;
    rsp_t    rsp_buf;
    p_cmd_t  pCmd = &cmd_buf;
    p_rsp_t  pRsp = &rsp_buf;

    stack_protection_init();

    /* Validate buffers. Both rsp & cmd should be allocated despite of further usage */
    if ( (tciBuffer == NULL) || 
         (tciBufferLen != sizeof(cmd_t)) )  {
        LOGE("Invalid tciBuffer pointer or size");
        pRsp->ret = -1;
        pRsp->status = -1;
        goto error;
    }

    LOGI("[INFO]:Start SEM TA :: Version: %s", SEMTA_VER);
    LOGD("SEM Trusted Application is waiting for a notification to arrive");

    for (;;) {
        /* Wait for a notification to arrive */
        tlApiWaitNotification(TLAPI_INFINITE_TIMEOUT);

        /* Replicate buffer to avoid of shared memory usage */
        memset(pCmd, 0, sizeof(cmd_t));
        memset(pRsp, 0, sizeof(rsp_t));
        memcpy(pCmd, tciBuffer, sizeof(cmd_t));

        /* Validate data buffer */
        if (pCmd->dataLen > MAX_DATA_SIZE)  {
            LOGE("Invalid cmd data buffer size");
            pRsp->ret = -1;
            pRsp->status = -1;
            goto error;
        }

        cmdHandler(pCmd->cmd_id, pCmd, pRsp);

        /* Copy back rsp buffer to shared memory */
        memcpy(tciBuffer, pRsp, sizeof(rsp_t));

error:
        /* Notify back the TLC */
        tlApiNotify();
    }
}
