#include "em_common.h"

static int em_cmd_set_version(em_context *ctx);
static int em_cmd_pre_processing(em_context *ctx);
static int em_cmd_processing(em_context *ctx);
static void em_cmd_print(uint32_t cmd);

#ifndef EMLITE
static int em_cmd_verify_esi_core(em_context *ctx);
static int em_cmd_post_processing(em_context *ctx);
#endif

int em_cmd_handler(em_context *ctx)
{
	int ret;

	EM_CHECK_NULL(__func__, EM_ERR_CMD_HANDLER, ctx);

	em_cmd_print(ctx->cmd);

	ret = em_cmd_set_version(ctx);
	if (ret != EM_SUCCESS) {
		LOGE("Failed to set version(0x%08x)\n", ret);
		goto out;
	}

	ret = em_cmd_pre_processing(ctx);
	if (ret != EM_SUCCESS) {
		LOGE("Failed to em_cmd_pre_processing(0x%08x)\n", ret);
		goto out;
	}

#ifndef EMLITE
	ret = em_cmd_verify_esi_core(ctx);
	if (ret != EM_SUCCESS) {
		LOGE("Failed to em_cmd_verify_esi_core(0x%08x)\n", ret);
		goto out;
	}
#endif

	ret = em_cmd_processing(ctx);
	if (ret != EM_SUCCESS) {
		LOGE("Failed to em_cmd_processing(0x%08x)\n", ret);
		goto out;
	}

#ifndef EMLITE
	ret = em_cmd_post_processing(ctx);
	if (ret != EM_SUCCESS) {
		LOGE("Failed to em_cmd_post_processing(0x%08x)\n", ret);
		goto out;
	}
#endif

	ret = EM_SUCCESS;
out:
	return ret;
}

#ifndef EMLITE
static int em_cmd_set_version(em_context *ctx)
{
	int ret = EM_SUCCESS;
	em_esi_meta meta = {0,};

	EM_CHECK_NULL(__func__, EM_ERR_EM_CMD_SET_VERSION, ctx);

	if (ctx->cmd == EM_CMD_INIT && ctx->flags[0] & EM_FLAGS_0_EXIST_BOOTLOADER &&
	    ctx->flags[0] & EM_FLAGS_0_EXIST_DID) {
		/* High priority for embs */
		if (em_is_all_zero(ctx->did, EM_LEN_DID) == EM_SUCCESS) {
			LOGE("did is all zero\n");
			ret = EM_ERR_EM_CMD_SET_VERSION_DID_ALL_ZERO;
			goto out;
		}
		if (memcmp(ctx->did, EM_MAGIC_VERSION20, strlen(EM_MAGIC_VERSION20)) == 0) {
			ctx->em_version = EM_VERSION20;
		} else {
			LOGE("Unknown bootloader did(%s)\n", ctx->did);
			ret = EM_ERR_EM_CMD_SET_VERSION_UNKNOWN_BL_DID_VERSION;
			goto out;
		}
		goto out;
	}

	if ((ctx->flags[0] & EM_FLAGS_0_EXIST_ESI) &&
	    (memcmp(ctx->esi + EM_LEN_ESI_DIGEST, EM_MAGIC_ESI, strlen(EM_MAGIC_ESI)) == 0)) {
		em_esi_read_meta(&meta, ctx->esi);
		if (meta.version == EM_VERSION20) {
			ctx->em_version = EM_VERSION20;
		} else {
			LOGE("Unknown meta version(%u)\n", meta.version);
			ret = EM_ERR_EM_CMD_SET_VERSION_UNKNOWN_META_VERSION;
			goto out;
		}
	} else if (ctx->flags[0] & EM_FLAGS_0_EXIST_DID) {
		/* Low prioirity for emas */
		if (em_is_all_zero(ctx->did, EM_LEN_DID) == EM_SUCCESS) {
			LOGE("did is all zero\n");
			ret = EM_ERR_EM_CMD_SET_VERSION_DID_ALL_ZERO;
			goto out;
		}
		if (memcmp(ctx->did, EM_MAGIC_VERSION20, strlen(EM_MAGIC_VERSION20)) == 0) {
			ctx->em_version = EM_VERSION20;
		} else {
			LOGE("Unknown did(%s)\n", ctx->did);
			ret = EM_ERR_EM_CMD_SET_VERSION_UNKNOWN_DID_VERSION;
			goto out;
		}
	} else {
		LOGE("Failed to check em version\n");
		ret = EM_ERR_EM_CMD_SET_VERSION_FAIL;
		goto out;
	}
out:
	if (ret == EM_SUCCESS)
		LOGI("EM version is %u\n", ctx->em_version);

	return ret;
}
#else
static int em_cmd_set_version(em_context *ctx)
{
	int ret = EM_SUCCESS;

	EM_CHECK_NULL(__func__, EM_ERR_EM_CMD_SET_VERSION, ctx);

	if (ctx->flags[0] & EM_FLAGS_0_EXIST_DID) {
		if (em_is_all_zero(ctx->did, EM_LEN_DID) == EM_SUCCESS) {
			LOGE("did is all zero\n");
			ret = EM_ERR_EM_CMD_SET_VERSION_DID_ALL_ZERO;
			goto out;
		}

		if (memcmp(ctx->did, EM_MAGIC_VERSION15, strlen(EM_MAGIC_VERSION15)) == 0 ||
		    memcmp(ctx->did, EM_MAGIC_VERSION25, strlen(EM_MAGIC_VERSION25)) == 0) {
			ctx->em_version = EM_VERSION25;
		} else {
			LOGE("Unknown did(%s)\n", ctx->did);
			ret = EM_ERR_EM_CMD_SET_VERSION_UNKNOWN_DID_VERSION;
			goto out;
		}
	} else {
		LOGE("Failed to check em version\n");
		ret = EM_ERR_EM_CMD_SET_VERSION_FAIL;
		goto out;
	}
out:
	if (ret == EM_SUCCESS)
		LOGI("EM version is %u\n", ctx->em_version);

	return ret;
}
#endif // EMLITE

#ifndef EMLITE
static int em_cmd_verify_esi_core(em_context *ctx)
{
	int ret;
	uint8_t *raw_core_v20 = NULL;
	uint8_t we_need_esi_key = 0;
	uint32_t offset = 0;

	EM_CHECK_NULL(__func__, EM_ERR_EM_CMD_VERIFY_ESI_CORE, ctx);

	if (ctx->flags[1] & EM_FLAGS_1_DO_INIT_CORE || ctx->flags[2] & EM_FLAGS_2_ENABLED_LSEC_TOKEN ||
	    ctx->flags[2] & EM_FLAGS_2_NO_NEED_CORE) {
		ret = EM_SUCCESS;
		goto out;
	}

	if (ctx->is_provision) {
		raw_core_v20 = (uint8_t *)em_calloc(1, EM_LEN_CORE_V20);
		if (raw_core_v20 == NULL) {
			LOGE("Failed to allocate raw core buf\n");
			ret = EM_ERR_EM_CMD_VERIFY_ESI_CORE_ALLOC_CORE;
			goto out;
		}

		ret = em_read_core(raw_core_v20, EM_LEN_CORE_V20);
		if (ret == EM_SUCCESS) {
			em_get_data_from_raw(ctx->core_v20.magic, EM_LEN_MAGIC_CORE_V20, raw_core_v20, EM_LEN_CORE_V20,
					     &offset, EM_LEN_MAGIC_CORE_V20);
			em_get_data_from_raw(ctx->core_v20.gcm_tag, EM_LEN_GCM_TAG_CORE_V20, raw_core_v20,
					     EM_LEN_CORE_V20, &offset, EM_LEN_GCM_TAG_CORE_V20);
			em_get_data_from_raw(ctx->core_v20.key, EM_LEN_KEY_CORE_V20, raw_core_v20, EM_LEN_CORE_V20,
					     &offset, EM_LEN_KEY_CORE_V20);
			em_get_data_from_raw((uint8_t *)&(ctx->core_v20.esi_ctr), (uint32_t)sizeof(uint32_t),
					     raw_core_v20, EM_LEN_CORE_V20, &offset, (uint32_t)sizeof(uint32_t));
			em_get_data_from_raw((uint8_t *)&(ctx->core_v20.flags), (uint32_t)sizeof(uint32_t),
					     raw_core_v20, EM_LEN_CORE_V20, &offset, (uint32_t)sizeof(uint32_t));
			em_get_data_from_raw((uint8_t *)&(ctx->core_v20.recovery_ctr), (uint32_t)sizeof(uint32_t),
					     raw_core_v20, EM_LEN_CORE_V20, &offset, (uint32_t)sizeof(uint32_t));
			em_get_data_from_raw(ctx->core_v20.iin, EM_LEN_IIN, raw_core_v20, EM_LEN_CORE_V20, &offset,
					     EM_LEN_IIN);
			em_get_data_from_raw((uint8_t *)&(ctx->core_v20.ta_rp), (uint32_t)sizeof(uint32_t),
					     raw_core_v20, EM_LEN_CORE_V20, &offset, (uint32_t)sizeof(uint32_t));
		} else {
			if ((uint32_t)ret == EM_ERR_EM_READ_CORE_ALL_ZERO) {
				LOGE("Core is all zero(0x%08x)\n", ret);
				memset(&(ctx->core_v20), 0, sizeof(em_core_v20));
			} else {
				LOGE("Failed to read core(0x%08x)\n", ret);
				goto out;
			}
		}
	}

	if (ctx->flags[2] & EM_FLAGS_2_PASS_VERIFY_ESI_CORE) {
		ret = EM_SUCCESS;
		goto out;
	}

	ret = em_esi_check_validation_v20(ctx);
	if (ret == EM_SUCCESS_RECOVERY_COUNTER) {
		ctx->flags[1] |= EM_FLAGS_1_EXIST_RETURN_ESI;
	} else if (ret != EM_SUCCESS) {
		LOGE("Failed to check esi validation(0x%08x)\n", ret);
		ctx->flags[1] |= EM_FLAGS_1_NEED_RECOVERY_ESI;
		goto out;
	}

	ret = em_esi_get_item(ctx->esi, EM_TYPE_ESI_ITEM_DID, ctx->did, EM_LEN_DID);
	if (ret != EM_SUCCESS) {
		LOGE("Failed to get did from esi(0x%08x)\n", ret);
		goto out;
	}

	if (ctx->is_provision) {
		if (em_is_all_zero((uint8_t *)&(ctx->core_v20), sizeof(em_core_v20)) == EM_SUCCESS) {
			we_need_esi_key = 1;
		} else if (memcmp(ctx->core_v20.magic, EM_MAGIC_EM_CORE, strlen(EM_MAGIC_EM_CORE)) == 0) {
			memcpy(ctx->key, ctx->core_v20.key, EM_LEN_KEY_CORE_V20);
		} else {
			LOGE("Core isn't normal\n");
			ret = EM_ERR_EM_CMD_VERIFY_ESI_CORE_CORE_ISNT_NORMAL;
			goto out;
		}
	} else {
		LOGI("Rpmb isn't provisioned\n");
		we_need_esi_key = 1;
	}

	if (we_need_esi_key == 1) {
		ret = em_esi_get_item(ctx->esi, EM_TYPE_ESI_ITEM_SHARED_KEY, ctx->key, EM_LEN_KEY_CORE_V20);
		if (ret != EM_SUCCESS) {
			LOGE("Failed to get key from esi(0x%08x)\n", ret);
			goto out;
		}
	}

	ret = EM_SUCCESS;
out:

	if (raw_core_v20)
		em_free(raw_core_v20);

	return ret;
}
#endif // NO EM LITE

static int em_cmd_pre_processing(em_context *ctx)
{
	int ret;

	switch (ctx->cmd) {
	case EM_CMD_GET_STATUS:
		ctx->flags[2] |= EM_FLAGS_2_NEED_TO_PARSING_TOKEN;
		break;
	case EM_CMD_INSTALL_TOKEN:
		ctx->flags[2] |= EM_FLAGS_2_NEED_TO_PARSING_TOKEN;
		break;
	case EM_CMD_TOKEN_IS_INSTALLED:
		ctx->flags[2] |= EM_FLAGS_2_NEED_TO_PARSING_TOKEN;
		break;
	case EM_CMD_GET_EXPIRYDATE:
		ctx->flags[2] |= EM_FLAGS_2_NEED_TO_PARSING_TOKEN;
		break;
	case EM_CMD_TOKEN_REQUEST:
		break;
	case EM_CMD_ESS:
		break;
	case EM_CMD_RECOVERY:
		ctx->flags[2] |= EM_FLAGS_2_PASS_VERIFY_ESI_CORE;
		break;
	case EM_CMD_MAKE_ITL_REQ:
		ctx->flags[2] |= EM_FLAGS_2_PASS_VERIFY_ESI_CORE;
		ctx->flags[2] |= EM_FLAGS_2_PASS_POST_PROCESSING;
		break;
	case EM_CMD_GET_TUC:
		break;
	case EM_CMD_SET_PRIORITY_TIME_ESS_V1:
		ctx->flags[2] |= EM_FLAGS_2_NEED_TO_PARSING_TOKEN;
		ctx->flags[2] |= EM_FLAGS_2_BUT_ITS_OK_NO_TOKEN;
		break;
	case EM_CMD_GET_PRIORITY_TIME_ESS_V1:
		ctx->flags[2] |= EM_FLAGS_2_NEED_TO_PARSING_TOKEN;
		ctx->flags[2] |= EM_FLAGS_2_BUT_ITS_OK_NO_TOKEN;
		break;
	case EM_CMD_GET_LAST_TOKEN_STATUS:
		break;
	case EM_CMD_GET_MODES:
		ctx->flags[2] |= EM_FLAGS_2_NEED_TO_PARSING_TOKEN;
		ctx->flags[2] |= EM_FLAGS_2_BUT_ITS_OK_NO_TOKEN;
		break;
	case EM_CMD_GET_MODES_BIT:
		ctx->flags[2] |= EM_FLAGS_2_NEED_TO_PARSING_TOKEN;
		break;
	case EM_CMD_GET_TOKEN_INFO_FOR_JANUS:
		ctx->flags[2] |= EM_FLAGS_2_NEED_TO_PARSING_TOKEN;
		break;
	case EM_CMD_TIME_REQUEST:
		ctx->flags[2] |= EM_FLAGS_2_NEED_TO_PARSING_TOKEN;
		ctx->flags[2] |= EM_FLAGS_2_NEED_TO_READ_DID;
		break;
	case EM_CMD_TIME_CHECK:
		ctx->flags[2] |= EM_FLAGS_2_NEED_TO_PARSING_TOKEN;
		ctx->flags[2] |= EM_FLAGS_2_NEED_TO_READ_DID;
		break;
	case EM_CMD_INIT:
		ctx->flags[2] |= EM_FLAGS_2_PASS_VERIFY_ESI_CORE;
		break;
	case EM_CMD_SUPPORT_ESS_V1:
		ctx->flags[2] |= EM_FLAGS_2_PASS_VERIFY_ESI_CORE;
		ctx->flags[2] |= EM_FLAGS_2_NO_NEED_CORE;
		ctx->flags[2] |= EM_FLAGS_2_PASS_POST_PROCESSING;
		break;
	case EM_CMD_GET_MODES_ESS_V1:
		ctx->flags[2] |= EM_FLAGS_2_NEED_TO_PARSING_TOKEN;
		ctx->flags[2] |= EM_FLAGS_2_BUT_ITS_OK_NO_TOKEN;
		break;
	case EM_CMD_REQ_TOKEN_ESS_V1:
		break;
	case EM_CMD_REQ_RECOVERY_ESS_V1:
		ctx->flags[2] |= EM_FLAGS_2_PASS_VERIFY_ESI_CORE;
		ctx->flags[2] |= EM_FLAGS_2_PASS_POST_PROCESSING;
		break;
	case EM_CMD_DELETE_TOKEN_ESS_V1:
		break;
	case EM_CMD_INSTALL_TOKEN_ESS_V1:
		break;
	case EM_CMD_RECOVERY_ESS_V1:
		ctx->flags[2] |= EM_FLAGS_2_PASS_VERIFY_ESI_CORE;
		break;
	case EM_CMD_INIT_CORE:
		ctx->flags[2] |= EM_FLAGS_2_NEED_TO_PARSING_TOKEN;
		ctx->flags[2] |= EM_FLAGS_2_PASS_VERIFY_ESI_CORE;
		ctx->flags[2] |= EM_FLAGS_2_PASS_POST_PROCESSING;
		ctx->flags[2] |= EM_FLAGS_2_NO_NEED_CORE;
		break;
	case EM_CMD_GET_MODES_FT:
		ctx->flags[2] |= EM_FLAGS_2_NEED_TO_PARSING_TOKEN;
		break;
	case EM_CMD_GET_INFO:
		ctx->flags[2] |= EM_FLAGS_2_NEED_TO_PARSING_TOKEN;
		break;
	case EM_CMD_GET_INFO_ESS_V1:
		ctx->flags[2] |= EM_FLAGS_2_NEED_TO_PARSING_TOKEN;
		ctx->flags[2] |= EM_FLAGS_2_BUT_ITS_OK_NO_TOKEN;
		break;
	}

#ifndef EMLITE
	if (ctx->flags[2] & EM_FLAGS_2_NEED_TO_READ_DID) {
		ret = em_esi_get_item(ctx->esi, EM_TYPE_ESI_ITEM_DID, ctx->did, EM_LEN_DID);
		if (ret != EM_SUCCESS) {
			LOGE("Failed to get did from esi(0x%08x)\n", ret);
			goto out;
		}
	}
#endif

	if (ctx->flags[2] & EM_FLAGS_2_NEED_TO_PARSING_TOKEN) {
		if (!(ctx->flags[0] & EM_FLAGS_0_EXIST_TOKEN)) {
			LOGE("There is no token in context(0x%08x)", ctx->cmd);
			ret = EM_ERR_EM_CMD_PRE_PROCESSING_NO_TOKEN;
			goto out;
		}

		ctx->parsed_token = (em_parsed_token *)em_calloc(sizeof(em_parsed_token), 1);
		EM_CHECK_NULL(__func__, EM_ERR_EM_CMD_PRE_PROCESSING, ctx->parsed_token);

		ret = em_token_verify_token(ctx, ctx->parsed_token, &ctx->token_ptr);
		if (ret != EM_SUCCESS) {
			LOGE("Failed to verify token(0x%08x)\n", ret);
			if (!(ctx->flags[2] & EM_FLAGS_2_BUT_ITS_OK_NO_TOKEN)) {
				goto out;
			} else {
				LOGI("But it's ok!(0x%08x)\n", ctx->cmd);
				ctx->flags[2] |= EM_FLAGS_2_TOKEN_VERIFICATION_FAILED;
			}
		}

		if (ctx->flags[2] & EM_FLAGS_2_ENABLED_LSEC_TOKEN)
			ctx->flags[2] |= EM_FLAGS_2_PASS_VERIFY_ESI_CORE | EM_FLAGS_2_PASS_POST_PROCESSING;

#ifndef EMLITE
		if (ctx->cmd == EM_CMD_INSTALL_TOKEN && (ctx->flags[0] & EM_FLAGS_0_EXIST_BOOTLOADER)) {
			ret = em_do_init_core(ctx);
			if (ret == EM_SUCCESS) {
				LOGI("bl core is initialized\n");
				ctx->flags[2] |= EM_FLAGS_2_PASS_VERIFY_ESI_CORE | EM_FLAGS_2_PASS_POST_PROCESSING;
			}
		}
#endif
	}

	ret = EM_SUCCESS;
out:
	return ret;
}

#ifndef EMLITE
static int em_cmd_post_processing(em_context *ctx)
{
	int ret;

	if (ctx->flags[2] & EM_FLAGS_2_PASS_POST_PROCESSING || !(ctx->flags[0] & EM_FLAGS_0_EXIST_ESI)) {
		ret = EM_SUCCESS;
		goto out;
	}

	if ((ctx->flags[0] & EM_FLAGS_0_EXIST_BOOTLOADER) && ((em_is_all_zero(ctx->esi, EM_LEN_ESI)) == EM_SUCCESS) &&
	    (ctx->cmd == EM_CMD_INIT)) {
		ret = EM_SUCCESS;
		goto out;
	}

	ret = em_esi_check_validation_v20(ctx);
	if (ret == EM_SUCCESS) {
		LOGE("Validate!!\n");
	} else if (ret == EM_SUCCESS_RECOVERY_COUNTER) {
		ctx->flags[1] |= EM_FLAGS_1_EXIST_RETURN_ESI;
		ret = EM_SUCCESS;
	}

out:
	memset(ctx->key, 0, EM_LEN_KEY_CORE_V20);

	return ret;
}
#endif // NO EMLITE

static int em_cmd_processing(em_context *ctx)
{
	int ret;

	EM_CHECK_NULL(__func__, EM_ERR_EM_CMD_PROCESSING, ctx);

	switch (ctx->cmd) {
	case EM_CMD_GET_STATUS:
		ret = em_token_get_status(ctx);
		break;
	case EM_CMD_INSTALL_TOKEN:
		if (ctx->flags[1] & EM_FLAGS_1_DO_INIT_CORE) {
			ret = EM_SUCCESS;
			goto out;
		}
		ret = em_token_install(ctx);
		break;
	case EM_CMD_TOKEN_IS_INSTALLED:
		ret = em_token_is_installed(ctx);
		break;
	case EM_CMD_GET_TUC:
		ret = em_token_get_usage_count(ctx);
		break;
	case EM_CMD_GET_MODES:
		ret = em_token_get_mode_information(ctx);
		break;
	case EM_CMD_GET_MODES_BIT:
		ret = em_token_get_mode_information_for_bit(ctx);
		break;
	case EM_CMD_ESS:
	case EM_CMD_REQ_TOKEN_ESS_V1:
	case EM_CMD_INSTALL_TOKEN_ESS_V1:
	case EM_CMD_DELETE_TOKEN_ESS_V1:
	case EM_CMD_REQ_RECOVERY_ESS_V1:
	case EM_CMD_RECOVERY_ESS_V1:
	case EM_CMD_SUPPORT_ESS_V1:
	case EM_CMD_GET_MODES_ESS_V1:
	case EM_CMD_GET_PRIORITY_TIME_ESS_V1:
	case EM_CMD_SET_PRIORITY_TIME_ESS_V1:
	case EM_CMD_GET_INFO_ESS_V1:
		ret = em_ess_command(ctx);
		break;
	case EM_CMD_TOKEN_REQUEST:
		ret = em_request_token(ctx->message, &ctx->len_message, ctx->flags, ctx->did, &ctx->keep, ctx->imei,
				       ctx->model_name, ctx->otp, ctx->single_id, ctx->modes, ctx->cnt_mode, ctx->date);
		break;
	case EM_CMD_TIME_REQUEST:
		ret = em_request_time(ctx->message, &ctx->len_message, ctx);
		break;
	case EM_CMD_TIME_CHECK:
		ret = em_token_check_time_msg(ctx->message, ctx->len_message, ctx);
		break;
	case EM_CMD_GET_MODES_FT:
		ret = em_ft_token_mode(ctx);
		break;
	case EM_CMD_GET_INFO:
		ret = em_token_get_info(ctx);
		break;
#ifndef EMLITE
	case EM_CMD_INIT:
		ret = em_init_v20(ctx);
		break;
	case EM_CMD_MAKE_ITL_REQ:
		ret = em_request_recovery(ctx);
		break;
	case EM_CMD_RECOVERY:
		ret = em_esi_recovery(ctx);
		break;
	case EM_CMD_INIT_CORE:
		ret = em_do_init_core(ctx);
		break;
#endif // EMLITE
	default:
		LOGE("Unknown command(0x%08x)\n", ctx->cmd);
		ret = EM_ERR_EM_CMD_PROCESSING_UNKNOWN_COMMAND;
		goto out;
	}

	if (ret != EM_SUCCESS) {
		LOGE("Failed to process command(0x%04x/0x%08x)\n", ctx->cmd, ret);
		goto out;
	}

	ret = EM_SUCCESS;
out:
	return ret;
}

static void em_cmd_print(uint32_t cmd)
{
	switch (cmd) {
	case EM_CMD_GET_STATUS:
		LOGW("EM_CMD_GET_STATUS\n");
		break;
	case EM_CMD_INIT:
		LOGW("EM_CMD_INIT\n");
		break;
	case EM_CMD_INSTALL_TOKEN:
		LOGW("EM_CMD_INSTALL_TOKEN\n");
		break;
	case EM_CMD_TOKEN_IS_INSTALLED:
		LOGW("EM_CMD_TOKEN_IS_INSTALLED\n");
		break;
	case EM_CMD_GET_TUC:
		LOGW("EM_CMD_GET_TUC\n");
		break;
	case EM_CMD_GET_MODES:
		LOGW("EM_CMD_GET_MODES\n");
		break;
	case EM_CMD_GET_MODES_BIT:
		LOGW("EM_CMD_GET_MODES_BIT\n");
		break;
	case EM_CMD_ESS:
		LOGW("EM_CMD_ESS\n");
		break;
	case EM_CMD_REQ_TOKEN_ESS_V1:
		LOGW("EM_CMD_REQ_TOKEN_ESS_V1\n");
		break;
	case EM_CMD_INSTALL_TOKEN_ESS_V1:
		LOGW("EM_CMD_INSTALL_TOKEN_ESS_V1\n");
		break;
	case EM_CMD_DELETE_TOKEN_ESS_V1:
		LOGW("EM_CMD_DELETE_TOKEN_ESS_V1\n");
		break;
	case EM_CMD_REQ_RECOVERY_ESS_V1:
		LOGW("EM_CMD_REQ_RECOVERY_ESS_V1\n");
		break;
	case EM_CMD_RECOVERY_ESS_V1:
		LOGW("EM_CMD_RECOVERY_ESS_V1\n");
		break;
	case EM_CMD_SUPPORT_ESS_V1:
		LOGW("EM_CMD_SUPPORT_ESS_V1\n");
		break;
	case EM_CMD_GET_MODES_ESS_V1:
		LOGW("EM_CMD_GET_MODES_ESS_V1\n");
		break;
	case EM_CMD_TOKEN_REQUEST:
		LOGW("EM_CMD_TOKEN_REQUEST\n");
		break;
	case EM_CMD_TIME_REQUEST:
		LOGW("EM_CMD_TIME_REQUEST\n");
		break;
	case EM_CMD_TIME_CHECK:
		LOGW("EM_CMD_TIME_CHECK\n");
		break;
	case EM_CMD_INIT_CORE:
		LOGW("EM_CMD_INIT_CORE\n");
		break;
	case EM_CMD_GET_MODES_FT:
		LOGW("EM_CMD_GET_MODES_FT\n");
		break;
	case EM_CMD_GET_INFO:
		LOGW("EM_CMD_GET_INFO\n");
		break;
	case EM_CMD_GET_INFO_ESS_V1:
		LOGW("EM_CMD_GET_INFO_ESS_V1\n");
		break;
	default:
		LOGE("Unknown command(0x%08x)\n", cmd);
	}
}
