/*
 * app_main.c
 */

#include <stdio.h>
#include <string.h>
#include <unistd.h>

#include <tee_internal_api.h>
#include <tees_extension.h>

#include "app_property.h"

#include "app_main.h"

#include "icccOperations_grdm.h"

static tciMessage_t sendMsgCopy;
static tciMessage_t rspMsgCopy;

TEE_Result TA_CreateEntryPoint(void)
{
    printf("%s TA_CreateEntryPoint \n", TA_TAG);
    return TEE_SUCCESS;
}

void TA_DestroyEntryPoint(void)
{
    printf("%s TA_DestroyEntryPoint \n", TA_TAG);
}

TEE_Result TA_OpenSessionEntryPoint(uint32_t paramTypes, TEE_Param params[4], void **sessionContext)
{
    printf("%s TA_OpenSessionEntryPoint \n", TA_TAG);
    (void) paramTypes;
    (void) params;
    (void) sessionContext;

    return TEE_SUCCESS;
}

void TA_CloseSessionEntryPoint(void *sessionContext)
{
    printf("%s TA_CloseSessionEntryPoint \n", TA_TAG);
    (void) sessionContext;
}

uint32_t grdm_ICCC_get_rot_test(iccc_test_payload_t *sendmsg, iccc_test_payload_t *respmsg)
{
    uint32_t ret = TZ_GRDM_ICCC_SUCCESS;

    grdm_rot_status_t rot_credential_buffer;
/*
    grdm_default_device_status_t device_status_buffer;

    if (TZ_GRDM_ICCC_SUCCESS == grdm_ICCC_getDeviceROTStat((uint32_t *)&device_status_buffer)) {
        printf("%s : current GRDM status in GRDM ICCC : %d", TA_TAG, device_status_buffer.grdm_status);
        printf("%s : current DEV RoT status in GRDM ICCC : %d", TA_TAG, device_status_buffer.dev_rot_status);
        if (device_status_buffer.dev_rot_status == 1) {
            if (TZ_GRDM_ICCC_SUCCESS == grdm_ICCC_getDefaultROTCredential((uint32_t *)&rot_credential_buffer)) {
                printf("%s : verified_boot_state %#x", TA_TAG, rot_credential_buffer.verified_boot_state);
                printf("%s : device_locked %#x", TA_TAG, rot_credential_buffer.device_locked);
                printf("%s : os_version %#x", TA_TAG, rot_credential_buffer.os_version);
                //getStringValueFromROT(OSVERSION_FLAG, rot_credential_buffer.os_version);
                printf("%s : patch_month_year %#x", TA_TAG, rot_credential_buffer.patch_month_year);
                //getStringValueFromROT(PATCHMONTHYEAR_FLAG, rot_credential_buffer.patch_month_year);
                for (int cnt = 0; cnt < 8; cnt++) {
                    printf("%s : verified_boot_key[%d] %#x", TA_TAG, cnt, rot_credential_buffer.verified_boot_key[cnt]);
                }
                printf("%s : boot_patch_level %#x", TA_TAG, rot_credential_buffer.boot_patch_level);
                //getStringValueFromROT(BOOTPATCHLEVEL_FLAG, rot_credential_buffer.boot_patch_level);
                printf("%s : vendor_patch_level %#x", TA_TAG, rot_credential_buffer.vendor_patch_level);
                //getStringValueFromROT(VENDORPATCHLEVEL_FLAG, rot_credential_buffer.vendor_patch_level);
                for (int cnt = 0; cnt < 8; cnt++) {
                    printf("%s : verified_boot_hash[%d] %#x", TA_TAG, cnt, rot_credential_buffer.verified_boot_hash[cnt]);
                }
                memcpy(&respmsg->content.iccc_test_rsp.grdm_rot_cred, &rot_credential_buffer, sizeof(rot_credential_buffer));
            } else {
                printf("%s : grdm_ICCC_getDefaultROTCredential failure", TA_TAG);
                ret = TZ_GRDM_ICCC_ERROR_DEFAULT_ROT_GET_FAILED;
            }
        } else {
 */
            if (TZ_GRDM_ICCC_SUCCESS == grdm_ICCC_getROTCredential((uint32_t *)&rot_credential_buffer)) {
                printf("%s : verified_boot_state %#x \n", TA_TAG, rot_credential_buffer.verified_boot_state);
                printf("%s : device_locked %#x \n", TA_TAG, rot_credential_buffer.device_locked);
                printf("%s : os_version %#x \n", TA_TAG, rot_credential_buffer.os_version);
                //getStringValueFromROT(OSVERSION_FLAG, rot_credential_buffer.os_version);
                printf("%s : patch_month_year %#x \n", TA_TAG, rot_credential_buffer.patch_month_year);
                //getStringValueFromROT(PATCHMONTHYEAR_FLAG, rot_credential_buffer.patch_month_year);
                for (int cnt = 0; cnt < 8; cnt++) {
                    printf("%s : verified_boot_key[%d] %#x \n", TA_TAG, cnt, rot_credential_buffer.verified_boot_key[cnt]);
                }
                printf("%s : boot_patch_level %#x \n", TA_TAG, rot_credential_buffer.boot_patch_level);
                //getStringValueFromROT(BOOTPATCHLEVEL_FLAG, rot_credential_buffer.boot_patch_level);
                printf("%s : vendor_patch_level %#x \n", TA_TAG, rot_credential_buffer.vendor_patch_level);
                //getStringValueFromROT(VENDORPATCHLEVEL_FLAG, rot_credential_buffer.vendor_patch_level);
                for (int cnt = 0; cnt < 8; cnt++) {
                    printf("%s : verified_boot_hash[%d] %#x \n", TA_TAG, cnt, rot_credential_buffer.verified_boot_hash[cnt]);
                }
                memcpy(&respmsg->content.iccc_test_rsp.grdm_rot_cred, &rot_credential_buffer, sizeof(rot_credential_buffer));
            } else {
                printf("%s : grdm_ICCC_getROTCredential failure \n", TA_TAG);
                ret = TZ_GRDM_ICCC_ERROR_ROT_GET_FAILED;
            }
/*
        }
    } else {
        printf("%s : grdm_ICCC_getDeviceROTStat failure", TA_TAG);
        ret = TZ_GRDM_ICCC_ERROR_GET_DEV_ROT_STAT_FAILED;
    }
 */
    respmsg->content.iccc_test_rsp.ret = ret;
    return ret;
}

uint32_t grdm_ICCC_get_bl_test(iccc_test_payload_t *sendmsg, iccc_test_payload_t *respmsg)
{
    uint32_t ret = TZ_GRDM_ICCC_SUCCESS;

    grdm_bl_status_t bl_credential_buffer;
/*
    grdm_default_device_status_t device_status_buffer;

    if (TZ_GRDM_ICCC_SUCCESS == grdm_ICCC_getDeviceROTStat((uint32_t *)&device_status_buffer)) {
        printf("%s : current GRDM status in GRDM ICCC : %d", TA_TAG, device_status_buffer.grdm_status);
        printf("%s : current DEV RoT status in GRDM ICCC : %d", TA_TAG, device_status_buffer.dev_rot_status);
        if (device_status_buffer.dev_rot_status == 1) {
            if (TZ_GRDM_ICCC_SUCCESS == grdm_ICCC_getDefaultBLCredential((uint32_t *)&bl_credential_buffer)) {
                printf("%s : rp_ver %#x", TA_TAG, bl_credential_buffer.rp_ver);
                printf("%s : kernel_rp %#x", TA_TAG, bl_credential_buffer.kernel_rp);
                printf("%s : system_rp %#x", TA_TAG, bl_credential_buffer.system_rp);
                printf("%s : test_bit %#x", TA_TAG, bl_credential_buffer.test_bit);
                printf("%s : sec_boot %#x", TA_TAG, bl_credential_buffer.sec_boot);
                printf("%s : react_lock %#x", TA_TAG, bl_credential_buffer.react_lock);
                printf("%s : kiwi_lock %#x", TA_TAG, bl_credential_buffer.kiwi_lock);
                printf("%s : frp_lock %#x", TA_TAG, bl_credential_buffer.frp_lock);
                printf("%s : cc_mode %#x", TA_TAG, bl_credential_buffer.cc_mode);
                printf("%s : mdm_mode %#x", TA_TAG, bl_credential_buffer.mdm_mode);
                printf("%s : curr_bin_status %#x", TA_TAG, bl_credential_buffer.curr_bin_status);
                printf("%s : afw_value %#x", TA_TAG, bl_credential_buffer.afw_value);
                printf("%s : warranty_bit %#x", TA_TAG, bl_credential_buffer.warranty_bit);
                printf("%s : kap_status %#x", TA_TAG, bl_credential_buffer.kap_status);
                for (int cnt = 0; cnt < 12; cnt++) {
                    printf("%s : image_status[%d] %#x", TA_TAG, cnt, bl_credential_buffer.image_status[cnt]);
                }
                printf("%s : image_status_bl %#x", TA_TAG, bl_credential_buffer.image_status_bl);
                printf("%s : WbHistory %#x", TA_TAG, bl_credential_buffer.WbHistory);
                printf("%s : ap_serial_0 %#x", TA_TAG, bl_credential_buffer.ap_serial_0);
                printf("%s : ap_serial_1 %#x", TA_TAG, bl_credential_buffer.ap_serial_1);
                printf("%s : em_status %#x", TA_TAG, bl_credential_buffer.em_status);
                printf("%s : em_token %#x", TA_TAG, bl_credential_buffer.em_token);
                printf("%s : trustboot_flag %#x", TA_TAG, bl_credential_buffer.trustboot_flag);
                memcpy(&respmsg->content.iccc_test_rsp.grdm_bl_cred, &bl_credential_buffer, sizeof(bl_credential_buffer));
            } else {
                printf("%s : grdm_ICCC_getDefaultBLCredential failure", TA_TAG);
                ret = TZ_GRDM_ICCC_ERROR_DEFAULT_BL_GET_FAILED;
            }
        } else {
 */
            if (TZ_GRDM_ICCC_SUCCESS == grdm_ICCC_getBLCredential((uint32_t *)&bl_credential_buffer)) {
                printf("%s : rp_ver %#x \n", TA_TAG, bl_credential_buffer.rp_ver);
                printf("%s : kernel_rp %#x \n", TA_TAG, bl_credential_buffer.kernel_rp);
                printf("%s : system_rp %#x \n", TA_TAG, bl_credential_buffer.system_rp);
                printf("%s : test_bit %#x \n", TA_TAG, bl_credential_buffer.test_bit);
                printf("%s : sec_boot %#x \n", TA_TAG, bl_credential_buffer.sec_boot);
                printf("%s : react_lock %#x \n", TA_TAG, bl_credential_buffer.react_lock);
                printf("%s : kiwi_lock %#x \n", TA_TAG, bl_credential_buffer.kiwi_lock);
                printf("%s : frp_lock %#x \n", TA_TAG, bl_credential_buffer.frp_lock);
                printf("%s : cc_mode %#x \n", TA_TAG, bl_credential_buffer.cc_mode);
                printf("%s : mdm_mode %#x \n", TA_TAG, bl_credential_buffer.mdm_mode);
                printf("%s : curr_bin_status %#x \n", TA_TAG, bl_credential_buffer.curr_bin_status);
                printf("%s : afw_value %#x \n", TA_TAG, bl_credential_buffer.afw_value);
                printf("%s : warranty_bit %#x \n", TA_TAG, bl_credential_buffer.warranty_bit);
                printf("%s : kap_status %#x \n", TA_TAG, bl_credential_buffer.kap_status);
                for (int cnt = 0; cnt < 12; cnt++) {
                    printf("%s : image_status[%d] %#x \n", TA_TAG, cnt, bl_credential_buffer.image_status[cnt]);
                }
                printf("%s : image_status_bl %#x \n", TA_TAG, bl_credential_buffer.image_status_bl);
                printf("%s : WbHistory %#x \n", TA_TAG, bl_credential_buffer.WbHistory);
                printf("%s : ap_serial_0 %#x \n", TA_TAG, bl_credential_buffer.ap_serial_0);
                printf("%s : ap_serial_1 %#x \n", TA_TAG, bl_credential_buffer.ap_serial_1);
                printf("%s : em_status %#x \n", TA_TAG, bl_credential_buffer.em_status);
                printf("%s : em_token %#x \n", TA_TAG, bl_credential_buffer.em_token);
                printf("%s : trustboot_flag %#x \n", TA_TAG, bl_credential_buffer.trustboot_flag);
                memcpy(&respmsg->content.iccc_test_rsp.grdm_bl_cred, &bl_credential_buffer, sizeof(bl_credential_buffer));
            } else {
                printf("%s : grdm_ICCC_getBLCredential failure \n", TA_TAG);
                ret = TZ_GRDM_ICCC_ERROR_BL_GET_FAILED;
            }
/*
        }
    } else {
        printf("%s : grdm_ICCC_getDeviceROTStat failure", TA_TAG);
        ret = TZ_GRDM_ICCC_ERROR_GET_DEV_ROT_STAT_FAILED;
    }
 */
    respmsg->content.iccc_test_rsp.ret = ret;
    return ret;
}

uint32_t grdm_ICCC_get_iccc_test(iccc_test_payload_t *sendmsg, iccc_test_payload_t *respmsg)
{
    uint32_t ret = TZ_GRDM_ICCC_SUCCESS;

    grdm_iccc_credential_1_t iccc_credential_buffer_1;
    grdm_iccc_credential_2_t iccc_credential_buffer_2;

    uint32_t type = sendmsg->content.iccc_req.type;
    switch (type) {
        case ATN_BLOB_HASH_FLAG:
            if (TZ_GRDM_ICCC_SUCCESS == grdm_ICCC_getCredential(ATN_BLOB_HASH_FLAG, (uint32_t *)&iccc_credential_buffer_1)) {
                for (int cnt = 0; cnt < 8; cnt++) {
                    printf("%s : atn_blob_hash[%d] %#x \n", TA_TAG, cnt, iccc_credential_buffer_1.atn_blob_hash[cnt]);
                }
                memcpy(&respmsg->content.iccc_test_rsp.grdm_iccc_cred1, &iccc_credential_buffer_1, sizeof(iccc_credential_buffer_1));
            } else {
                printf("%s : grdm_ICCC_getCredential failure \n", TA_TAG);
                ret = TZ_GRDM_ICCC_ERROR_ICCC_GET_FAILED;
            }
            break;
        case ICCC_VERSION_FLAG:
            if (TZ_GRDM_ICCC_SUCCESS == grdm_ICCC_getCredential(ICCC_VERSION_FLAG, (uint32_t *)&iccc_credential_buffer_2)) {
                printf("%s : iccc_version %#x \n", TA_TAG, iccc_credential_buffer_2.iccc_version);
                memcpy(&respmsg->content.iccc_test_rsp.grdm_iccc_cred2, &iccc_credential_buffer_2, sizeof(iccc_credential_buffer_2));
            } else {
                printf("%s : grdm_ICCC_getCredential failure \n", TA_TAG);
                ret = TZ_GRDM_ICCC_ERROR_ICCC_GET_FAILED;
            }
            break;
        default:
            printf("%s : grdm_ICCC_getCredential failure \n", TA_TAG);
            ret = TZ_GRDM_ICCC_ERROR_NOT_SUPPORT;
            break;
    }

    respmsg->content.iccc_test_rsp.ret = ret;
    return ret;
}

uint32_t grdm_ICCC_set_iccc_test(iccc_test_payload_t *sendmsg, iccc_test_payload_t *respmsg)
{
    uint32_t ret = TZ_GRDM_ICCC_SUCCESS;
    uint8_t atn_blob_hash[32] = {0x52, 0x94, 0x31, 0xc2, 0x09, 0xce, 0x01, 0x2a, 0xda, 0xda, 0x58, 0xc4, 0xc9, 0x7f, 0xf2, 0xb4,
                                 0xa2, 0x23, 0x68, 0x90, 0xf7, 0x27, 0x39, 0xb1, 0x8e, 0xd0, 0xda, 0xe3, 0xcb, 0x48, 0x98, 0x2c };

    grdm_iccc_credential_1_t iccc_credential_buffer_1;
    memcpy(&iccc_credential_buffer_1.atn_blob_hash, atn_blob_hash, sizeof(atn_blob_hash));
    grdm_iccc_credential_2_t iccc_credential_buffer_2;
    iccc_credential_buffer_2.iccc_version = 1;

    uint32_t type = sendmsg->content.iccc_req.type;
    switch (type) {
        case ATN_BLOB_HASH_FLAG:
            for (int cnt = 0; cnt < 8; cnt++) {
                printf("%s : atn_blob_hash[%d] %#x \n", TA_TAG, cnt, iccc_credential_buffer_1.atn_blob_hash[cnt]);
            }
            if (TZ_GRDM_ICCC_SUCCESS == grdm_ICCC_storeCredential(ATN_BLOB_HASH_FLAG, (uint32_t *)&iccc_credential_buffer_1)) {
                printf("%s : grdm_ICCC_setCredential success \n", TA_TAG);
            } else {
                printf("%s : grdm_ICCC_setCredential failure \n", TA_TAG);
                ret = TZ_GRDM_ICCC_ERROR_ICCC_SET_FAILED;
            }
            break;
        case ICCC_VERSION_FLAG:
            printf("%s : iccc_version %d \n", TA_TAG, iccc_credential_buffer_2.iccc_version);
            if (TZ_GRDM_ICCC_SUCCESS == grdm_ICCC_storeCredential(ICCC_VERSION_FLAG, (uint32_t *)&iccc_credential_buffer_2)) {
                printf("%s : grdm_ICCC_setCredential success \n", TA_TAG);
            } else {
                printf("%s : grdm_ICCC_setCredential failure \n", TA_TAG);
                ret = TZ_GRDM_ICCC_ERROR_ICCC_SET_FAILED;
            }
            break;
        default:
            printf("%s : grdm_ICCC_setCredential failure \n", TA_TAG);
            ret = TZ_GRDM_ICCC_ERROR_NOT_SUPPORT;
            break;
    }

    respmsg->content.iccc_test_rsp.ret = ret;
    return ret;
}

uint32_t grdm_ICCC_del_iccc_test(iccc_test_payload_t *sendmsg, iccc_test_payload_t *respmsg)
{
    uint32_t ret = TZ_GRDM_ICCC_SUCCESS;

    uint32_t type = sendmsg->content.iccc_req.type;
    switch (type) {
        case ATN_BLOB_HASH_FLAG:
            if (TZ_GRDM_ICCC_SUCCESS == grdm_ICCC_deleteCredential(ATN_BLOB_HASH_FLAG)) {
                printf("%s : grdm_ICCC_deleteCredential success \n", TA_TAG);
            } else {
                printf("%s : grdm_ICCC_deleteCredential failure \n", TA_TAG);
                ret = TZ_GRDM_ICCC_ERROR_ICCC_DEL_FAILED;
            }
            break;
        case ICCC_VERSION_FLAG:
            if (TZ_GRDM_ICCC_SUCCESS == grdm_ICCC_deleteCredential(ICCC_VERSION_FLAG)) {
                printf("%s : grdm_ICCC_deleteCredential success \n", TA_TAG);
            } else {
                printf("%s : grdm_ICCC_deleteCredential failure \n", TA_TAG);
                ret = TZ_GRDM_ICCC_ERROR_ICCC_DEL_FAILED;
            }
            break;
        default:
            printf("%s : grdm_ICCC_setCredential failure \n", TA_TAG);
            ret = TZ_GRDM_ICCC_ERROR_NOT_SUPPORT;
            break;
    }

    respmsg->content.iccc_test_rsp.ret = ret;
    return ret;
}

uint32_t grdm_negative(iccc_test_payload_t *sendmsg, iccc_test_payload_t *respmsg)
{
    uint32_t ret = TZ_GRDM_ICCC_SUCCESS;

    grdm_iccc_credential_1_t iccc_credential_buffer_1;
    uint32_t ng_flag = 0;

    // grdm_ICCC_getROTCredential
    if (TZ_GRDM_ICCC_SUCCESS == grdm_ICCC_getROTCredential(NULL)) { // grdm_ICCC_getROTCredential : buffer is NULL
        printf("%s : grdm_ICCC_getROTCredential success \n", TA_TAG);
    } else {
        printf("%s : grdm_ICCC_getROTCredential failure \n", TA_TAG);
        ret = TZ_GRDM_ICCC_ERROR_ROT_GET_FAILED;
    }
    // grdm_ICCC_getBLCredential
    if (TZ_GRDM_ICCC_SUCCESS == grdm_ICCC_getBLCredential(NULL)) { // grdm_ICCC_getBLCredential : buffer is NULL
        printf("%s : grdm_ICCC_getBLCredential success \n", TA_TAG);
    } else {
        printf("%s : grdm_ICCC_getBLCredential failure \n", TA_TAG);
        ret = TZ_GRDM_ICCC_ERROR_ROT_GET_FAILED;
    }
    // grdm_ICCC_getCredential
    if (TZ_GRDM_ICCC_SUCCESS == grdm_ICCC_getCredential(ng_flag, (uint32_t *)&iccc_credential_buffer_1)) { // grdm_ICCC_getCredential : failed, cannot get the credential data (permission)
        printf("%s : grdm_ICCC_getCredential success \n", TA_TAG);
    } else {
        printf("%s : grdm_ICCC_getCredential failure \n", TA_TAG);
        ret = TZ_GRDM_ICCC_ERROR_ICCC_GET_FAILED;
    }
    if (TZ_GRDM_ICCC_SUCCESS == grdm_ICCC_getCredential(ATN_BLOB_HASH_FLAG, NULL)) { // grdm_ICCC_getCredential : buffer is NULL
        printf("%s : grdm_ICCC_getCredential success \n", TA_TAG);
    } else {
        printf("%s : grdm_ICCC_getCredential failure \n", TA_TAG);
        ret = TZ_GRDM_ICCC_ERROR_ICCC_GET_FAILED;
    }
    if (TZ_GRDM_ICCC_SUCCESS == grdm_ICCC_getCredential(ICCC_VERSION_FLAG, NULL)) { // grdm_ICCC_getCredential : buffer is NULL
        printf("%s : grdm_ICCC_getCredential success \n", TA_TAG);
    } else {
        printf("%s : grdm_ICCC_getCredential failure \n", TA_TAG);
        ret = TZ_GRDM_ICCC_ERROR_ICCC_GET_FAILED;
    }
    if (TZ_GRDM_ICCC_SUCCESS == grdm_ICCC_getCredential(ng_flag, NULL)) { // grdm_ICCC_getCredential : buffer is NULL
        printf("%s : grdm_ICCC_getCredential success \n", TA_TAG);
    } else {
        printf("%s : grdm_ICCC_getCredential failure \n", TA_TAG);
        ret = TZ_GRDM_ICCC_ERROR_ICCC_GET_FAILED;
    }
    if (TZ_GRDM_ICCC_SUCCESS == grdm_ICCC_getCredential(NULL, (uint32_t *)&iccc_credential_buffer_1)) { // grdm_ICCC_getCredential : failed, cannot get the credential data (permission)
        printf("%s : grdm_ICCC_getCredential success \n", TA_TAG);
    } else {
        printf("%s : grdm_ICCC_getCredential failure \n", TA_TAG);
        ret = TZ_GRDM_ICCC_ERROR_ICCC_GET_FAILED;
    }
    if (TZ_GRDM_ICCC_SUCCESS == grdm_ICCC_getCredential(NULL, NULL)) { // grdm_ICCC_getCredential : buffer is NULL
        printf("%s : grdm_ICCC_getCredential success \n", TA_TAG);
    } else {
        printf("%s : grdm_ICCC_getCredential failure \n", TA_TAG);
        ret = TZ_GRDM_ICCC_ERROR_ICCC_GET_FAILED;
    }
    // grdm_ICCC_storeCredential
    if (TZ_GRDM_ICCC_SUCCESS == grdm_ICCC_storeCredential(ATN_BLOB_HASH_FLAG, NULL)) { // grdm_ICCC_storeCredential : buffer is NULL
        printf("%s : grdm_ICCC_storeCredential success \n", TA_TAG);
    } else {
        printf("%s : grdm_ICCC_storeCredential failure \n", TA_TAG);
        ret = TZ_GRDM_ICCC_ERROR_ICCC_SET_FAILED;
    }
    if (TZ_GRDM_ICCC_SUCCESS == grdm_ICCC_storeCredential(ng_flag, NULL)) { // grdm_ICCC_storeCredential : buffer is NULL
        printf("%s : grdm_ICCC_storeCredential success \n", TA_TAG);
    } else {
        printf("%s : grdm_ICCC_storeCredential failure \n", TA_TAG);
        ret = TZ_GRDM_ICCC_ERROR_ICCC_SET_FAILED;
    }
    if (TZ_GRDM_ICCC_SUCCESS == grdm_ICCC_storeCredential(NULL, (uint32_t *)&iccc_credential_buffer_1)) { // TZ_GRDM_ICCC_UNKNOWN_TYPE
        printf("%s : grdm_ICCC_storeCredential success \n", TA_TAG);
    } else {
        printf("%s : grdm_ICCC_storeCredential failure \n", TA_TAG);
        ret = TZ_GRDM_ICCC_ERROR_ICCC_SET_FAILED;
    }
    if (TZ_GRDM_ICCC_SUCCESS == grdm_ICCC_storeCredential(NULL, NULL)) { // grdm_ICCC_storeCredential : buffer is NULL
        printf("%s : grdm_ICCC_storeCredential success \n", TA_TAG);
    } else {
        printf("%s : grdm_ICCC_storeCredential failure \n", TA_TAG);
        ret = TZ_GRDM_ICCC_ERROR_ICCC_SET_FAILED;
    }
    // grdm_ICCC_deleteCredential
    if (TZ_GRDM_ICCC_SUCCESS == grdm_ICCC_deleteCredential(ng_flag)) { // grdm_ICCC_deleteCredential : ret - (-1001) (permission)
        printf("%s : grdm_ICCC_deleteCredential success \n", TA_TAG);
    } else {
        printf("%s : grdm_ICCC_deleteCredential failure \n", TA_TAG);
        ret = TZ_GRDM_ICCC_ERROR_ICCC_DEL_FAILED;
    }

    respmsg->content.iccc_test_rsp.ret = ret;
    return ret;
}

uint32_t process_cmd(uint32_t commandId, tciMessage_t *sendmsg, tciMessage_t *respmsg)
{
    uint32_t ret = TZ_GRDM_ICCC_SUCCESS;

    /* Process command message */
    switch (commandId) {
        case CMD_ICCC_GRDM_GET_ROT_CRED_TEST:
            printf("%s : cmd case CMD_ICCC_GRDM_GET_ROT_CRED_TEST \n", TA_TAG);
            ret = grdm_ICCC_get_rot_test(&sendmsg->payload.test, &respmsg->payload.test);
            break;
        case CMD_ICCC_GRDM_GET_BL_CRED_TEST:
            printf("%s : cmd case CMD_ICCC_GRDM_GET_BL_CRED_TEST \n", TA_TAG);
            ret = grdm_ICCC_get_bl_test(&sendmsg->payload.test, &respmsg->payload.test);
            break;
        case CMD_ICCC_GRDM_GET_ICCC_CRED_TEST:
            printf("%s : cmd case CMD_ICCC_GRDM_GET_ICCC_CRED_TEST \n", TA_TAG);
            ret = grdm_ICCC_get_iccc_test(&sendmsg->payload.test, &respmsg->payload.test);
            break;
        case CMD_ICCC_GRDM_SET_ICCC_CRED_TEST:
            printf("%s : cmd case CMD_ICCC_GRDM_SET_ICCC_CRED_TEST \n", TA_TAG);
            ret = grdm_ICCC_set_iccc_test(&sendmsg->payload.test, &respmsg->payload.test);
            break;
        case CMD_ICCC_GRDM_DEL_ICCC_CRED_TEST:
            printf("%s : cmd case CMD_ICCC_GRDM_DEL_ICCC_CRED_TEST \n", TA_TAG);
            ret = grdm_ICCC_del_iccc_test(&sendmsg->payload.test, &respmsg->payload.test);
            break;
        case CMD_ICCC_GRDM_TEST_NEGATIVE:
            printf("%s : cmd case CMD_ICCC_GRDM_TEST_NEGATIVE \n", TA_TAG);
            ret = grdm_negative(&sendmsg->payload.test, &respmsg->payload.test);
            break;
        default:
            printf("%s : received unknown command: %d! \n", TA_TAG, commandId);
            ret = TZ_GRDM_ICCC_UNKNOWN_CMD;
            respmsg->payload.generic.content.iccc_rsp.ret = ret;
            break;
    }

    printf("%s process_cmd: ret: %d \n", TA_TAG, ret);
    return ret;
}

/* Trustlet entry */
TEE_Result TA_InvokeCommandEntryPoint(void *sessionContext, uint32_t commandID, uint32_t paramTypes, TEE_Param params[4])
{
    printf("%s TA_InvokeCommandEntryPoint \n", TA_TAG);

    uint32_t ret = TEE_SUCCESS;
    uint32_t commandId;
    tciMessage_t* sendmsg = NULL;
    tciMessage_t* respmsg = NULL;

    printf("%s tz buildinfo: build %s, teegris %s, chipset %s \n", TA_TAG, TARGET_BUILD_VARIANT, TEEGRIS_VERSION, TEEGRIS_BUILD_MODEL);
    printf("%s paramTypes: %d, TEE_PARAM_TYPES: %d \n", TA_TAG,
                       paramTypes, TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, TEE_PARAM_TYPE_MEMREF_OUTPUT, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE));
    if (paramTypes != (uint32_t)TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, TEE_PARAM_TYPE_MEMREF_OUTPUT, TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE)) {
        printf("%s Bad Parameters in TA_InvokeCommandEntryPoint \n", TA_TAG);
        return TEE_ERROR_BAD_PARAMETERS;
    }

    /* Entry if session was open from NW */
    if (params[0].memref.buffer == NULL || params[1].memref.buffer == NULL ||
        params[0].memref.size < sizeof(tciMessage_t) || params[1].memref.size < sizeof(tciMessage_t)) {
        printf("%s Shared memory buffer size check error \n", TA_TAG);
        return TEE_ERROR_BAD_PARAMETERS;
    }

    if (TEES_IsREESharedMemory (TEE_MEMORY_ACCESS_READ | TEE_MEMORY_ACCESS_WRITE, params[0].memref.buffer, params[0].memref.size) != TEE_SUCCESS ||
        TEES_IsREESharedMemory (TEE_MEMORY_ACCESS_WRITE, params[1].memref.buffer, params[1].memref.size) != TEE_SUCCESS) {
        printf("%s TEES_IsREESharedMemory access check error \n", TA_TAG);
        return TEE_ERROR_ACCESS_DENIED;
    }

    /* Local buffer to prevent Race Condition */
    TEE_MemFill(&sendMsgCopy, 0, sizeof(tciMessage_t));
    TEE_MemFill(&rspMsgCopy, 0, sizeof(tciMessage_t));
    TEE_MemMove(&sendMsgCopy, params[0].memref.buffer, sizeof(tciMessage_t));

    sendmsg = &sendMsgCopy;
    respmsg = &rspMsgCopy;

    ret = process_cmd(commandID, sendmsg, respmsg);

    respmsg->header.id = RSP_ID(commandID);
    respmsg->header.status = ret;

    TEE_MemMove(params[1].memref.buffer, &rspMsgCopy, sizeof(tciMessage_t));
    TEE_MemFill(&sendMsgCopy, 0, sizeof(tciMessage_t));
    TEE_MemFill(&rspMsgCopy, 0, sizeof(tciMessage_t));

    return TEE_SUCCESS;
}
