#ifndef __EM_CONTEXT_H
#define __EM_CONTEXT_H

/*
 * It will be shared em_tlc.so
 */

#pragma pack(push, 1)
typedef struct em_context_t {
	uint32_t cmd;
	uint64_t flags[EM_LEN_PAYLOAD_FLAGS];

	uint8_t did[EM_LEN_DID];
	uint8_t imei[EM_LEN_IMEI];
	uint8_t single_id[EM_LEN_SINGLE_ID];
	uint8_t model_name[EM_LEN_MODEL_NAME];
	uint8_t otp[EM_LEN_OTP];
	uint8_t date[EM_LEN_DATE];

	uint8_t client_proc_name[EM_LEN_CLIENT_PROC_NAME];
	uint8_t client_pkg_name[EM_LEN_CLIENT_PKG_NAME];
	uint32_t client_uid;
	uint32_t client_signature;

	uint16_t cnt_mode;
	uint16_t modes[EM_LEN_MODE_BUFFER];

	uint32_t cnt_validity;
	uint8_t osversion[EM_LEN_OSVERSION];
	uint8_t swversion[EM_LEN_SWVERSION];
	uint8_t blversion[EM_LEN_BLVERSION];
	uint32_t tss;
	uint32_t activated;
	uint8_t serial[EM_LEN_UNIQUE];
	uint8_t smsn[EM_LEN_SMSN]; // 934

	uint8_t reserved[218];// Don't add item to above

	uint8_t token[EM_LEN_TOKEN];

	uint32_t len_message;
	uint8_t message[EM_LEN_MESSAGE];

	uint32_t len_cert;
	uint8_t cert[EM_LEN_CERTIFICATE];

	uint32_t len_ess_prefixbody;
	uint8_t ess_prefixbody[EM_LEN_ESS_PREFIX_BODY];
	uint8_t ess_nonce[EM_LEN_NONCE];
	uint8_t ess_iv_b64[EM_LEN_ESS_IV_B64];
	uint8_t ess_etoken_b64[EM_LEN_TOKEN];
	uint8_t ess_command_type[1 + 1];

	uint8_t recovery_data[EM_LEN_RECOVERY_DATA];

	uint8_t esi[EM_LEN_ESI];

	uint8_t esi_version;
	uint8_t is_provision;
	uint8_t key[EM_LEN_KEY_CORE_V20];
	em_keeping_item keep;
	uint32_t ret_temp;
	uint64_t mode_bits[EM_LEN_GET_MODES_BIT_BUFFER];
} em_context;
#pragma pack(pop)

#pragma pack(push, 1)
typedef struct em_req_payload_primary_t {
	uint32_t cmd;
	uint64_t flags[EM_LEN_PAYLOAD_FLAGS];

	uint8_t did[EM_LEN_DID];
	uint8_t imei[EM_LEN_IMEI];
	uint8_t single_id[EM_LEN_SINGLE_ID];
	uint8_t model_name[EM_LEN_MODEL_NAME];
	uint8_t otp[EM_LEN_OTP];
	uint8_t date[EM_LEN_DATE];

	uint8_t client_proc_name[EM_LEN_CLIENT_PROC_NAME];
	uint8_t client_pkg_name[EM_LEN_CLIENT_PKG_NAME];
	uint32_t client_uid;
	uint32_t client_signature;

	uint16_t cnt_mode;
	uint16_t modes[EM_LEN_MODE_BUFFER]; // 808

	uint32_t cnt_validity; //812

	uint8_t osversion[EM_LEN_OSVERSION];
	uint8_t swversion[EM_LEN_SWVERSION];
	uint8_t blversion[EM_LEN_BLVERSION]; // 878
	uint32_t tss;
	uint32_t activated;
	uint8_t serial[EM_LEN_UNIQUE];
	uint8_t smsn[EM_LEN_SMSN]; // 934

	em_keeping_item keep;
	uint8_t reserved[218]; // 1152 - 934
} em_req_payload_primary;
#pragma pack(pop)

#pragma pack(push, 1)
typedef struct em_req_payload_secondary_t {
	uint64_t flags[EM_LEN_PAYLOAD_FLAGS];

	uint8_t token[EM_LEN_TOKEN];

	uint32_t len_message;
	uint8_t message[EM_LEN_MESSAGE];

	uint32_t len_cert;
	uint8_t cert[EM_LEN_CERTIFICATE];

	uint32_t len_ess_prefixbody;
	uint8_t ess_prefixbody[EM_LEN_ESS_PREFIX_BODY];
	uint8_t ess_nonce[EM_LEN_NONCE];
	uint8_t ess_iv_b64[EM_LEN_ESS_IV_B64];

	uint8_t esi[EM_LEN_ESI];
} em_req_payload_secondary;
#pragma pack(pop)

#pragma pack(push, 1)
typedef struct em_rsp_payload_primary_t {
	uint32_t cmd;
	uint64_t flags[EM_LEN_PAYLOAD_FLAGS];

	em_keeping_item keep;
	uint64_t mode_bits[EM_LEN_GET_MODES_BIT_BUFFER];

	uint8_t reserved[984];
} em_rsp_payload_primary;
#pragma pack(pop)

#pragma pack(push, 1)
typedef struct em_rsp_payload_secondary_t {
	uint64_t flags[EM_LEN_PAYLOAD_FLAGS];

	uint8_t esi[EM_LEN_ESI];

	uint8_t token[EM_LEN_TOKEN];

	uint32_t type_message;
	uint32_t len_message;
	uint8_t message[EM_LEN_MESSAGE];
} em_rsp_payload_secondary;
#pragma pack(pop)

#pragma pack(push, 1)
typedef struct em_req_payload_t {
	uint8_t version;
	em_req_payload_primary primary;
	em_req_payload_secondary secondary;
} em_req_payload;
#pragma pack(pop)

#pragma pack(push, 1)
typedef struct em_rsp_payload_t {
	uint32_t ret;
	uint8_t version;
	em_rsp_payload_primary primary;
	em_rsp_payload_secondary secondary;
} em_rsp_payload;
#pragma pack(pop)

int em_context_make_request(uint8_t *req_buf, em_context *ctx);
int em_context_make_response(uint8_t *rsp_buf, em_context *ctx, uint32_t result);

#include "em_common.h"

#endif
