/*
 * blowfish_agent_main.c
 *
 * This source file is proprietary property of Samsung Electronics Co., Ltd.
 *
 * Copyright (C) 2011 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
 *
 * Contact: Roman Pasechnik <r.pasechnik@samsung.com>
 *
 */

#include "mldap_blowfish_TA.h"
#include <tee_internal_api.h>

#include "CommLayerData.h"
#include "CryptoPlatform.h"
#include "CommandHandler.h"
#include "log.h"
#include "version.h"

#define MMAP_AREA_SIZE  MAX_TRANSFER_SIZE

TEE_Result TA_CreateEntryPoint(void)
{
	return TEE_SUCCESS;
}

void TA_DestroyEntryPoint(void)
{
}

static unsigned int serial = 0;

TEE_Result TA_OpenSessionEntryPoint(uint32_t paramTypes,
	TEE_Param params[4], void **sessionContext)
{
	(void) paramTypes;
	(void) params;
	// (void) sessionContext;
	*sessionContext = (void *)serial++;
	return TEE_SUCCESS;
}

void TA_CloseSessionEntryPoint(void *sessionContext)
{
	(void) sessionContext;
}

TEE_Result TA_InvokeCommandEntryPoint(void *sessionContext, uint32_t commandID, uint32_t param_types, TEE_Param param[4])
{
	uint8_t* data = param[0].memref.buffer;
	uint32_t* dataLen = &param[0].memref.size;
	uint8_t dataOut[MAX_TRANSFER_SIZE];
	uint32_t dataOutLen = sizeof(dataOut);
	int32_t ret = 0;

	(void) sessionContext;
	(void) commandID;
	(void) param_types;

	cmd_req_t cmd_buf;

	if (data == NULL || *dataLen > MAX_TRANSFER_SIZE) {
		LOGI("invalid parameters..\n");
		ret = WRONG_DATA;
		goto out;
	}

	if (TEE_PARAM_TYPE_GET(param_types, 0) != TEE_PARAM_TYPE_MEMREF_INOUT) {
		LOGI("invalid parameters..\n");
		ret = WRONG_DATA;
		goto out;
	}
#if defined(SDK_VER_V3) || defined(SDK_VER_V4)
	else {
		if (TEES_IsREESharedMemory(TEE_MEMORY_ACCESS_READ,
						param[0].memref.buffer, param[0].memref.size) != TEE_SUCCESS) {
			LOGI("invalid parameters..\n");
			ret = WRONG_DATA;
			goto out;
		}
	}
#endif /* SDK_VER_V3 || SDK_VER_V4 */

	memset(&cmd_buf, 0, sizeof(cmd_req_t));
	cmd_buf.dataLen=*dataLen;
	memcpy(&cmd_buf.data, data, *dataLen);
	cmd_buf.cmd_id=(uint32_t)commandID;
	
	/* print trustlet name and version */
	LOGI("================================================\n");
	LOGI(" MLDAP trustlet v" VERSION "\n");
	LOGI("================================================\n");

	LOGD("Command id %d\n", commandID);

	ret = handleCmd(cmd_buf.cmd_id, &cmd_buf.data, cmd_buf.dataLen, dataOut, &dataOutLen);

	if (ret == NO_ERROR) {
		if (dataOutLen > MAX_TRANSFER_SIZE) {
			LOGE("Out data too big (%d bytes)\n", dataOutLen);
			ret = PLATFORM_INTERNAL_ERROR;
		} else {
			*dataLen = dataOutLen;
			memcpy(data, dataOut, dataOutLen);
		}
	}

out:
	LOGD("Return code %d\n", ret);
	LOGD("================================================\n");

	memset(&cmd_buf, 0, sizeof(cmd_req_t));
	return ret;
}
