/*
 * @file mposOperations.c
 * @brief Common code for TA-TA communication with tui ta
 * Copyright (c) 2020, Samsung Electronics Corporation. All rights reserved.
 */

#include "mposOperations.h"
#include "mpos_tata_common.h"
#include "tee_internal_api.h"
#include <stdio.h>

#define TAG "mposOperations: "

uint32_t mpos_tata_communication(mposMessage_t * sendmsg, mposMessage_t *respmsg, uint32_t commandID) {
	TEE_Result ret = MPOS_TATA_SUCCESS;
	TEE_UUID selected = MPOS_AUTH_UUID;
	TEE_TASessionHandle session;
	TEE_Param params[4];
	uint32_t returnOrigin = 0;
	uint32_t requestTimeout = 300;
	uint32_t paramTypes = TEE_PARAM_TYPES(TEE_PARAM_TYPE_MEMREF_INOUT, TEE_PARAM_TYPE_MEMREF_OUTPUT,
					      TEE_PARAM_TYPE_NONE, TEE_PARAM_TYPE_NONE);

	printf(TAG "Start communication TA-TA\n");

	ret = TEE_OpenTASession(&selected, requestTimeout, 0, NULL, &session, &returnOrigin);
	printf(TAG "TEE_OpenTASession - returnOrigin = %x \n", returnOrigin);
	if (ret != TEE_SUCCESS) {
		printf(TAG "TEE_OpenTASession - Error to open Session ret=%x \n", ret);
		ret = MPOS_ERROR_SESSION_FAILED;
	} else {
		params[0].memref.buffer = sendmsg;
		params[0].memref.size = sizeof(mposMessage_t);
		params[1].memref.buffer = respmsg;
		params[1].memref.size = sizeof(mposMessage_t);

		ret = TEE_InvokeTACommand(session, requestTimeout, commandID, paramTypes, params, &returnOrigin);
		respmsg = params[1].memref.buffer;
		if (ret != TEE_SUCCESS) {
			printf(TAG "TEE_InvokeTACommand - Error to send TA Command ret=%x \n", ret);
			ret = MPOS_ERROR_COMMAND_FAILED;
		}

		TEE_CloseTASession(session);
		printf(TAG "TEE_CloseTASession \n");
	}

	return ret;
}

uint32_t TA_Communication_mpos_encrypt_pin(uint32_t g_pin_length, uint8_t *g_pin) {
	TEE_Result ret = MPOS_TATA_ERROR;
	mposMessage_t* sendmsg = NULL;
	mposMessage_t* respmsg = NULL;

	sendmsg = TEE_Malloc(sizeof(mposMessage_t), 0);
	if (sendmsg == NULL) {
		printf(TAG "TA_Communication_mpos_encrypt_pin: Failed to allocated sendmsg buffer");
		ret = MPOS_TATA_ERROR;
		goto free_resources;
	}

	respmsg = TEE_Malloc(sizeof(mposMessage_t), 0);
	if (respmsg == NULL) {
		printf(TAG "TA_Communication_mpos_encrypt_pin: Failed to allocated respmsg buffer");
		ret = MPOS_TATA_ERROR;
		goto free_resources;
	}

	if (g_pin_length > PIN_MAX_SIZE) {
		printf(TAG "TA_Communication_mpos_encrypt_pin: Pin is bigger than expected. Actual: %d, Expected: %d", g_pin_length, PIN_MAX_SIZE);
		ret = MPOS_TATA_ERROR;
		goto free_resources;
	}

	sendmsg->tata_message.g_pin_length = g_pin_length;
	// Shouldn't the structure use the MAX_PINSIZE constant?
	TEE_MemMove(sendmsg->tata_message.g_pin, g_pin, g_pin_length);

	ret = mpos_tata_communication(sendmsg, respmsg, CMD_MPOSAUTH_TATA_ENCRYPT_PIN);
	if (ret != MPOS_TATA_SUCCESS) {
		ret = MPOS_TATA_ERROR;
	}

	printf(TAG "TA_Communication_mpos_encrypt_pin : ret - (%d) \n", ret);

free_resources:
	TEE_Free(sendmsg);
	TEE_Free(respmsg);

	return ret;
}
