
/*
 * =====================================================================================
 *
 *       Filename:  app_main.c
 *
 *    Description:  HDM main
 *
 *        Version:  1.0
 *        Created:  09/16/2019 15:26:11 PM
 *       Revision:  none
 *       Compiler:  gcc
 *
 *        Company:  Samsung Electronics
 *        Copyright (c) 2015 by Samsung Electronics, All rights reserved.
 *
 * =====================================================================================
 */

/** Inlcudes */
#include "process_cmd.h"
#include <comdef.h>
#include "qsee_log.h"
#include "tz_hdm_interface.h"
#include "hdm_defs.h"
#include "tci.h"
#include "hdm_allowlist.h"

#include "CHDMKG.h"
#include "CHDMKG_open.h"

/**
 * @brief
 * Add any app specific initialization code here QSEE will call this
 * function after secure app is loaded and authenticated
 */
void tz_app_init(void) {
        /* Initialization of KG global variables */
        KGNonce = 0;
        KGOperation = 0;

        qsee_log(QSEE_LOG_MSG_DEBUG, "TZ_HDM Init");
}

/**
 * @brief
 * App specific command handler
 * App executes code based on input command
 *
 * @param[in] cmd     - command
 * @param[in] cmdlen  - command length
 * @param[out] *rsp   - response
 * @param[out] rsplen - response length
 */
void tz_app_cmd_handler(void *cmd, uint32 cmdlen, void *rsp, uint32 rsplen) {
        hdm_return_code_t ret = HDM_STATUS_SUCCESS;
        uint32_t commandId = 0;

        tci_message_t sendmsg;
        tci_message_t respmsg;

        if (NULL == cmd || cmdlen < sizeof(tci_message_t) || rsp == NULL || rsplen < sizeof(tci_message_t)
                || ((cmd < rsp) && ((void *)((uint8_t *)cmd + cmdlen) > rsp))
                || ((rsp < cmd) && ((void *)((uint8_t *)rsp + rsplen) > cmd))) {
                        HDM_LOG("APP_MAIN: fail to setup command handler due invalid input.");
                        HDM_LOG_DEBUG("APP_MAIN: cmd = %p, cmdlen = %d", cmd, cmdlen);
                        HDM_LOG_DEBUG("APP_MAIN: rsp = %p, rspLen = %d", rsp, rsplen);
                        HDM_LOG_DEBUG("APP_MAIN: tci_message_t len = %lu", sizeof(tci_message_t));
                        return ;
        }
        TEE_MemMove(&sendmsg, cmd, sizeof(tci_message_t));
        TEE_MemMove(&respmsg, rsp, sizeof(tci_message_t));

        commandId = sendmsg.header.id;
        HDM_LOG_DEBUG("command id - %08X", commandId);

        if (!IS_CMD(commandId)) {
                HDM_LOG("Invalid command id, exiting!");

                ret = HDM_STATUS_FAIL;
                goto exit;
        }

        ret = process_cmd(commandId, &sendmsg, &respmsg);

        if (commandId != CMD_BL_GET_STATUS && commandId != CMD_APPLY_POLICY) {
            switch(device_status) {
                case HDM_DEVICE_OK:
                        respmsg.content.server_comm.jws_message.policy_value = payload.device_block;
                        break;
                case HDM_DEVICE_COMPROMISED:
                        respmsg.content.server_comm.jws_message.policy_value = payload.compromise_block;
                        break;
                case HDM_APPLY_DEFAULT_POLICY:
                default:
                        respmsg.content.server_comm.jws_message.policy_value = HDM_DEFAULT_POLICY;
                        break;
            }
        }

        HDM_LOG_DEBUG("respmsg.jws_message.policy_value = %d", respmsg.content.server_comm.jws_message.policy_value);

        if (commandId == CMD_BL_GET_POLICY) {
                hdm_ICCC_save(respmsg.content.server_comm.jws_message.policy_value);
        }
exit:
        respmsg.header.id = RSP_ID(commandId);
        respmsg.header.status = ret;
        TEE_MemMove(cmd, &sendmsg, sizeof(tci_message_t));
        TEE_MemMove(rsp, &respmsg, sizeof(tci_message_t));

        /*TODO: HVC */
}

/** App Name */
char TZ_APP_NAME[] = {"tz_hdm"};

int32_t tz_module_open(uint32_t uid, Object cred, Object *objOut)
{
  uint32_t ret = Object_ERROR_INVALID;
  char caller_ta_name[32] = {0, };
  size_t caller_ta_name_size = 0;

  HDM_LOG("tz_hdm tz_module_open() uid: %d", uid);

  ret = get_app_name(cred, caller_ta_name, 32, &caller_ta_name_size);
  if (!Object_isOK(ret)) {
    qsee_log(QSEE_LOG_MSG_ERROR, "tz_hdm tz_module_open() error on get_app_name");
    goto error;
  }
  HDM_LOG_DEBUG("caller_ta_name = %s && caller_ta_name_size = %zu", caller_ta_name, caller_ta_name_size);

  switch (uid) {
    case CHDMKG_UID:
      return CHDMKG_open(cred, objOut);
    default:
      ret = Object_ERROR_INVALID;
      break;
  }

error:
  *objOut = Object_NULL;
  return ret;
}

/**
 * @brief
 * App specific shutdown
 * App will be given a chance to shutdown gracefully
 */
void tz_app_shutdown(void) {
        /* app specific shutdown code*/
        qsee_log(QSEE_LOG_MSG_DEBUG, "TZ_HDM shutdown");
        return;
}
