
/*
 * app_service.c
 */

#include <object.h>
#include <stdio.h>

#include "IICCCSaveData_invoke.h"
#include "CICCCSaveData.h"
#include "CICCCSaveData_open.h"
#include "IICCCReadData_invoke.h"
#include "CICCCReadData.h"
#include "CICCCReadData_open.h"
#include "IICCCGetDeviceStatus_invoke.h"
#include "CICCCGetDeviceStatus.h"
#include "CICCCGetDeviceStatus_open.h"

#include "app_core.h"
#include "app_saveData.h"
#include "app_readData.h"
#include "app_getDeviceStatus.h"
#include "app_allowlist.h"
#include "app_service.h"

/* ICCC Service */
// Null pointer global for use to alleviate build warnings seen when
// intentionally using a null pointer. Static assignment and use will result in a compiler warning.
void *null_ptr = NULL;

static inline int32_t
CICCCGetDeviceStatus_getDeviceStatus(void *cxt, uint32_t *ret, uint32_t comp_type_val, const void *caller_ta_name,
                                     uint32_t caller_ta_name_size, uint8_t *resp_msg_buf_ptr, size_t resp_msg_buf_len, size_t *resp_msg_buf_lenout,
                                     uint32_t *result_code_ptr)
{
    ICCC_LOG("TZ_ICCC: Starting CICCCGetDeviceStatus_getDeviceStatus()");

    char ta_name[TA_NAME_SIZE] = {0, };
    strncpy(ta_name, caller_ta_name, caller_ta_name_size);
    *ret = check_ta_cmd_permission(ta_name, caller_ta_name_size, CICCCGetDeviceStatus_UID);
    if (*ret != ICCC_SUCCESS) {
        ICCC_LOG("TZ_ICCC: check command permission failed %s on command %d, error %d", ta_name, CICCCGetDeviceStatus_UID, *ret);
        goto error;
    }

    *ret = Iccc_Core_DeviceStatus_TA(comp_type_val, resp_msg_buf_ptr, (uint32_t)resp_msg_buf_len, (uint32_t *)resp_msg_buf_lenout, result_code_ptr);
    ICCC_LOG("TZ_ICCC: CICCCGetDeviceStatus_getDeviceStatus() ret = %d, resp_msg_buf : %s", *ret, resp_msg_buf_ptr);

error:
    return Object_OK;
}

static inline int32_t
CICCCReadData_readData(void *cxt, uint32_t *ret, uint32_t type, const void *caller_ta_name,
                       uint32_t caller_ta_name_size, uint32_t *value, size_t value_len, size_t *value_lenout)
{
    ICCC_LOG("TZ_ICCC: Starting CICCCReadData_readData()");
    *value_lenout = 0;

    if (!is_type_valid(type)) {
        *ret = ICCC_UNKNOWN_TYPE;
        goto error;
    }

    char ta_name[TA_NAME_SIZE] = {0, };
    strncpy(ta_name, caller_ta_name, caller_ta_name_size);
    *ret = check_ta_cmd_type_permission(ta_name, caller_ta_name_size, CICCCReadData_UID, type);
    if (*ret != ICCC_SUCCESS) {
        ICCC_LOG("TZ_ICCC: check command type permission failed %s on command %d on type %d, error %d", ta_name, CICCCReadData_UID, type, *ret);
        goto error;
    }

    // Need to set value_lenout
    if (get_offset(type, value_lenout) == -1) {
        ICCC_LOG("TZ_ICCC: invalid type:%#x", type);
        *ret = ICCC_UNKNOWN_TYPE;
        goto error;
    }

    *ret = Iccc_Core_ReadData_TA(type, value);
    ICCC_LOG("TZ_ICCC: CICCCReadData_readData() ret = %d and value = 0x%x", *ret, *value);

error:
    return Object_OK;
}

static inline int32_t
CICCCSaveData_saveData(void *cxt, uint32_t *ret, uint32_t type, const void *caller_ta_name,
                       uint32_t caller_ta_name_size, const uint32_t *value, size_t value_len)
{
    ICCC_LOG("TZ_ICCC: Starting CICCCSaveData_saveData()");

    if (!is_type_valid(type)) {
        *ret = ICCC_UNKNOWN_TYPE;
        goto error;
    }

    char ta_name[TA_NAME_SIZE] = {0, };
    strncpy(ta_name, caller_ta_name, caller_ta_name_size);
    *ret = check_ta_cmd_type_permission(ta_name, caller_ta_name_size, CICCCSaveData_UID, type);
    if (*ret != ICCC_SUCCESS) {
        ICCC_LOG("TZ_ICCC: check command type permission failed %s on command %d on type %d, error %d", ta_name, CICCCSaveData_UID, type, *ret);
        goto error;
    }

    *ret = Iccc_Core_SaveData_TA(type, (uint32_t*)value);
    ICCC_LOG("TZ_ICCC: CICCCSaveData_saveData() ret = %d", *ret);

error:
    return Object_OK;
}

static IICCCGetDeviceStatus_DEFINE_INVOKE(CICCCGetDeviceStatus_invoke, CICCCGetDeviceStatus_, void*)
static IICCCReadData_DEFINE_INVOKE(CICCCReadData_invoke, CICCCReadData_, void*)
static IICCCSaveData_DEFINE_INVOKE(CICCCSaveData_invoke, CICCCSaveData_, void*)

int32_t CICCCGetDeviceStatus_open(Object cred, Object *objOut)
{
    ICCC_LOG("TZ_ICCC: CICCCGetDeviceStatus_open() ");

    *objOut = (Object) { CICCCGetDeviceStatus_invoke, NULL };
    return Object_OK;
}

int32_t CICCCReadData_open(Object cred, Object *objOut)
{
    ICCC_LOG("TZ_ICCC: CICCCReadData_open() ");

    *objOut = (Object) { CICCCReadData_invoke, NULL };
    return Object_OK;
}

int32_t CICCCSaveData_open(Object cred, Object *objOut)
{
    ICCC_LOG("TZ_ICCC: CICCCSaveData_open() ");

    *objOut = (Object) { CICCCSaveData_invoke, NULL };
    return Object_OK;
}

/* ICCC Service */
