/**
 * Copyright (C) 2011 Samsung Electronics Co., Ltd. All rights reserved.
 *
 * Mobile Communication Division,
 * Digital Media & Communications Business, Samsung Electronics Co., Ltd.
 *
 * This software and its documentation are confidential and proprietary
 * information of Samsung Electronics Co., Ltd.  No part of the software and
 * documents may be copied, reproduced, transmitted, translated, or reduced to
 * any electronic medium or machine-readable form without the prior written
 * consent of Samsung Electronics.
 *
 * Samsung Electronics makes no representations with respect to the contents,
 * and assumes no responsibility for any errors that might appear in the
 * software and documents. This publication and the contents hereof are subject
 * to change without notice.
 *
 */
 /**
 * @file hdcp2.h
 * @author
 * @date
 * @brief This file contains definition of all the functions used in NWD
 */

#ifndef _HDCP2_H_
#define _HDCP2_H_

#ifdef __cplusplus
extern "C" {
#endif

#include "version.h"
#include "hdcp2_common.h"

#ifdef USE_TEEGRIS
#include "tee_client_api.h"
#endif /* USE_TEEGRIS */

#include <time.h>

#ifdef DEBUG
#define HDCP2_DEBUG(format, ...) HDCP2_Log(format, __VA_ARGS__)
#else
#define HDCP2_DEBUG(format, ...)
#endif /* DEBUG */

// if this is set to 1, AKE will force to connect with receiver/repeater to 2.1 version
/**
 * @def HDCP2_ALWAYS_2_1
 *
 * This macro is assigned a value of 0 to be maintained everywhere.
 */
//#define HDCP2_PROFILE_ENCRYPT_TIME

/**
 * @def HDCP2_PAIRING_INFO_DIR
 *
 * This macro is assigned a value of "/data/system/hdcp2" to be maintained
 */
#define HDCP2_PAIRING_INFO_DIR	"/data/system/hdcp2"

/**
 * @def HDCP2_RECEIVER_PORT
 *
 * This macro is assigned a value of 9999 to be maintained everywhere.
 */
#define HDCP2_RECEIVER_PORT	9999

/**
 * @def HDCP_SRM_FILE
 *
 * This macro is assigned a value of "/system/etc/srm.bin" to be maintained
 * .
 */
#define HDCP_SRM_FILE	"/system/etc/srm.bin"

/**
 * @def HDCP2_TRANSMITTER
 *
 * This macro is assigned a value of 1 to be maintained everywhere.
 */
#define HDCP2_TRANSMITTER	1

/**
 * @def HDCP2_RECEIVER
 *
 * This macro is assigned a value of 2 to be maintained everywhere.
 */
#define HDCP2_RECEIVER	2

/**
 * @def HDCP2_REPEATER
 *
 * This macro is assigned a value of 3 to be maintained everywhere.
 */
#define HDCP2_REPEATER	3

/**
 * @def HDCP2_FACTORY
 *
 * This macro is assigned a value of 4 to be maintained everywhere.
 */
#define HDCP2_FACTORY	4

/**
 * @def REPEATER_SPC
 *
 */
#define REPEATER_SPC

// tztype

/**
 * @def TZ_TYPE_NONE
 *
 * This macro is assigned a value of 1 to be maintained everywhere.
 */
#define TZ_TYPE_NONE	1

/**
 * @def TZ_TYPE_SMC
 *
 * This macro is assigned a value of 2 to be maintained everywhere.
 */
#define TZ_TYPE_SMC	2

/**
 * @def TZ_TYPE_MOBICORE
 *
 * This macro is assigned a value of 3 to be maintained everywhere.
 */
#define TZ_TYPE_MOBICORE	3

/**
 * @def TZ_TYPE_MOBICORE
 *
 * This macro is assigned a value of 3 to be maintained everywhere.
 */
#define TZ_TYPE_TEEGRIS	4

/**
 * @def HDCP2_VERSION_2_0
 *
 * This macro is assigned a value of 20 to be maintained everywhere and it specifies the version of HDCP used.
 */
#define HDCP2_VERSION_2_0	20

/**
 * @def HDCP2_VERSION_2_1
 *
 * This macro is assigned a value of 21 to be maintained everywhere and it specifies the version of HDCP used.
 */
#define HDCP2_VERSION_2_1	21

/**
 * @def HDCP2_VERSION_2_2
 *
 * This macro is assigned a value of 22 to be maintained everywhere and it specifies the version of HDCP used.
 */
#define HDCP2_VERSION_2_2	22

/**
 * @def MAX_PATH_LEN
 *
 * This macro is assigned a value of 256 to be maintained everywhere.
 */
#define MAX_PATH_LEN	256

/**
 * @def MAX_NUM_STEAM_K
 *
 * This macro is assigned a value of 16 to be maintained everywhere.
 */
#define MAX_NUM_STEAM_K	16

/**
 * @def PAIRING_INFO_LENGTH
 *
 * This macro is assigned a value of 160 to be maintained everywhere.
 */
#define PAIRING_INFO_LENGTH	160

/**
 * @struct timestamp
 *
 * This structure contains information regarding the timestamp.
 */
typedef struct timeval_ {
	__time_t tv_sec; /* Seconds.  */
	__suseconds_t tv_usec; /* Microseconds.  */
} timestamp;

#ifdef USE_MOBICORE
/**
 * @struct secmem_region
 *
 * This structure contains information regarding secure memory region
 */
struct secmem_region {
	char *virt_addr;
	unsigned long phys_addr;
	unsigned long len;
};
#endif /* USE_MOBICORE */

/**
 * @enum msg
 *
 * This enum represents the authentication status
 */
typedef enum {
	HDCP2_AUTHENTICATION_SUCCESS, /* Authentication sucess */
	HDCP2_AUTHENTICATION_FAILED, /* Authentication failed */
	HDCP2_UPSTREAM_SHUTDOWN, /* Upstream device(Tx) shutdown */
	HDCP2_DOWNSTREAM_SHUTDOWN, /* Downstream device(Rx) shutdown */
	HDCP2_DOWNSTREAM_BLOCKED, /* Block the Downstream device(Rx 1.x) from transmission for stream type=1*/
	HDCP2_DOWNSTREAM_TYPE_CHANGE, /* There has been a type change in the streamed content to Rx */
	HDCP2_DOWNSTREAM_HDMI_ERROR, /* Issue with the HDMI Cable/Module in the downstream */
	HDCP2_INVALID_STATE /* Invalid state */
} msg;

/**
 * @enum ext1
 *
 * This enum represents the error type
 */
typedef enum {
	HDCP2_ERROR_NONE,
	HDCP2_ERROR_NETWORK,
	HDCP2_ERROR_NULL_REQUEST,
	HDCP2_ERROR_NULL_RESPONSE,
	HDCP2_ERROR_CRYPTO,
	HDCP2_ERROR_BLOCK_TRAMSMISSION,
	HDCP2_DOWNSTREAM_TYPE1_CONTENT,
	HDCP2_DOWNSTREAM_TYPE0_CONTENT,
	HDCP2_ERROR_HDMI_CABLE,
	HDCP2_ERROR_INVALID_STATE
} ext1;

/**
 * @struct HDCP2_Ctx
 *
 * This structure contains information regarding the HDCP context.
 */
typedef struct HDCP2_ {
	u8 entity;
	u8 receiver_id[5];
	u8 is_paired;
	u8 is_key_loaded;
	char pair_info_dir[MAX_PATH_LEN];
	char pair_info_path[MAX_PATH_LEN];
	unsigned char encrypted_pairing[PAIRING_INFO_LENGTH];
	u8 reserved[WRAPPED_KEY_SIZE];
	u8 tztype;
	int version;
	int opened;
	timestamp time_ake_start;
	timestamp time_pairing_done;
	timestamp time_ske_done;
	int csd;
	int running_ake;
	int tlc_opened;

#ifdef USE_MOBICORE
	addr_s input_physaddr;
	u8 *input_virtaddr;
	addr_s output_physaddr;
	u8 *output_virtaddr;
	mcSessionHandle_t sessionHandle;
	tci_t *tci;
	mcBulkMap_t mapInfo;
	struct secmem_region region_output;
	struct secmem_region region_input;
	mcVersionInfo_t versionInfo;
#endif /* USE_MOBICORE */

#if defined(USE_MOBICORE) || defined(USE_TEEGRIS)
	u8 hwinit;
	int input_ionfd;
	int output_ionfd;
#endif /* USE_MOBICORE || USE_TEEGRIS */

	struct secmem_buffer input_buf;
	struct secmem_buffer output_buf;

#ifdef USE_TEEGRIS
	TEEC_Session ga_sessionHandle;
#endif /* USE_TEEGRIS */

	u8 REPEATER;
	u8 no_of_streams[2];
	long timeout;
	int ake_retry_count;
	int lc_retry_count;
	int sd;
	u8 hdcp2_legacy_device_downstream;
	u8 hdcp1_device_downstream;
	u8 Tx_LC_Precompute;
	u8 Rx_LC_Precompute;
	u8 disable_Precompute;
	void (*observerNotify)(void *,  msg,  ext1, int);
	void *wfd_ctx;
	int ion_fd;
} HDCP2_Ctx;

/*Callback function which is to be defined in WFD for error handling*/
typedef void (*HDCP2Observer)(void *,  msg,  ext1, int);

typedef union {
	u8 *pa;
	u32 ih;
	int32_t fd;
} obp;

#ifdef USE_MOBICORE
/**
 *
 * @fn int TLC_COMMAND(HDCP2_Ctx *hdcp, const uint8_t command, uint8_t *request, uint32_t req_size, uint8_t *response, uint32_t res_size);
 * @brief This function transfers the control to the secure world when using mobicore
 * @param hdcp - pointer to HDCP context
 * @param command - specifies the command to be executed.
 * @param request - This is the pointer to the request buffer which holds data that has to be worked upon
 * @param req_size - specifies the size of request
 * @param response - This is the pointer to the response buffer that is generally populated in SWD and sent back to NWD
 * @param res_size - specifies the size of response
 * @return int
 */
int TLC_COMMAND(HDCP2_Ctx *hdcp, const uint8_t command, uint8_t *request, uint32_t req_size, uint8_t *response, uint32_t res_size);

/**
 *
 * @def TZ_COMMAND_T(x,y,y1,z,z1)
 * This maps the parameter of TZ_COMMAND to TLC_COMMAND while specifying for transmitter
 *
 */
#define TZ_COMMAND_T(x,y,y1,z,z1) TLC_COMMAND(hdcp, ((x)+CMD_TRANSMITTER),(y),(y1),(z),(z1))

/**
 *
 * @def TZ_COMMAND_R(x,y,y1,z,z1)
 *This maps the parameter of TZ_COMMAND to TLC_COMMAND while specifying for receiver.
 *
 */
#define TZ_COMMAND_R(x,y,y1,z,z1) TLC_COMMAND(hdcp, ((x)+CMD_RECEIVER),(y),(y1),(z),(z1))
#elif defined(USE_QUALCOMM)
int32_t QSEE_COMMAND(HDCP2_Ctx *hdcp, const uint8_t command, uint8_t *request, uint32_t req_size,
				uint8_t *response, uint32_t res_size);
int32_t QSEE_COMMAND_ION(const uint8_t command, uint8_t* request, uint32_t req_size, int ion_fd);

#define TZ_COMMAND_T(x,y,y1,z,z1) QSEE_COMMAND(hdcp, ((x)+CMD_TRANSMITTER),(y),(y1),(z),(z1))
#define TZ_COMMAND_R(x,y,y1,z,z1) QSEE_COMMAND(hdcp, ((x)+CMD_RECEIVER),(y),(y1),(z),(z1))
#define TZ_COMMAND_T_ION(x,y,y1,z) QSEE_COMMAND_ION(((x)+CMD_TRANSMITTER),(y),(y1),(z))
#define TZ_COMMAND_R_ION(x,y,y1,z) QSEE_COMMAND_ION(((x)+CMD_RECEIVER),(y),(y1),(z))
#elif defined(USE_TEEGRIS)
int TA_COMMAND(HDCP2_Ctx *hdcp, const uint8_t command, uint8_t *request, uint32_t req_size, uint8_t *response, uint32_t res_size);

#define TZ_COMMAND_T(x,y,y1,z,z1) TA_COMMAND(hdcp, ((x)+CMD_TRANSMITTER),(y),(y1),(z),(z1))
#define TZ_COMMAND_R(x,y,y1,z,z1) TA_COMMAND(hdcp, ((x)+CMD_RECEIVER),(y),(y1),(z),(z1))
#endif /* USE_MOBICORE */

// High level APIs
/**
 * @fn int HDCP2_IsKeyboxValid(HDCP2_Ctx *hdcp)
 * @brief Checks if the keybox is valid
 * @param hdcp - pointer to HDCP context
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int HDCP2_IsKeyboxValid(HDCP2_Ctx *hdcp);

/**
 * @fn int HDCP2_GetOemFlag(HDCP2_Ctx *hdcp, u32* flag)
 * @brief This functions checks for OEM information
 * @param hdcp - pointer to HDCP context
 * @param flag - The pointer to the OEM flag populated in this function
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int HDCP2_GetOemFlag(HDCP2_Ctx *hdcp, u32* flag);

/**
 * @fn int HDCP2_Init(HDCP2_Ctx *hdcp, u8 entity, int version)
 * @brief Initializes hdcp context
 * @param hdcp - pointer to HDCP context
 * @param entity - specifies if the devices is a transmitter or receiver or a repeater.
 * @param version - specifies the Hdcp version (2.0/2.1/2.2)
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int HDCP2_Init(HDCP2_Ctx *hdcp, u8 entity, int version);

/**
 * @fn int HDCP2_Close(HDCP2_Ctx *hdcp)
 * @brief Closes the hdcp connection by unintializing hdcp2 context
 * @param hdcp - pointer to HDCP context
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int HDCP2_Close(HDCP2_Ctx *hdcp);

/**
 * @fn int HDCP2_Connect(HDCP2_Ctx *hdcp, const char *address, const int port)
 * @brief It starts the hdcp connection
 * @param hdcp - pointer to HDCP context
 * @param address - pointer to IP address string
 * @param port - Port on which hdcp connection is to be made
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int HDCP2_Connect(HDCP2_Ctx *hdcp, const char *address, const int port);

/**
 * @fn int HDCP2_WrapKey(HDCP2_Ctx *hdcp)
 * @brief This function wraps key data for encryption
 * @param hdcp - pointer to HDCP context
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int HDCP2_WrapKey(HDCP2_Ctx *hdcp);

/**
 * @fn int HDCP2_WrapKeyData(HDCP2_Ctx *hdcp, const u8 *keyData, int keyDataLen)
 * @brief This function wraps key data for encryption and is called by hdcp2_Wrap_key
 * @param hdcp - pointer to HDCP context
 * @param keyData - pointer to the key
 * @param keyDataLen - length of key
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int HDCP2_WrapKeyData(HDCP2_Ctx *hdcp, const u8 *keyData, int keyDataLen);

/**
 * @fn int HDCP2_CopyToSecureMem(HDCP2_Ctx *hdcp, uint8_t* input, int inlen, uint8_t* output)
 * @brief copy data from input to output without decrypting
 * @param hdcp - pointer to HDCP context
 * @param input - pointer to data to be copied
 * @param inlen - length of input data
 * @param output - ion fd of the location where data is to be copied
 */
int HDCP2_CopyToSecureMem(HDCP2_Ctx *hdcp, uint8_t* input, int inlen, uint8_t* output);

/**
 * @fn int HDCP2_Encrypt(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_ctr, u8 *input, int inlen, u8 *output)
 * @brief This function encrypts the data.
 * @param hdcp - pointer to HDCP context
 * @param str_ctr - It is 32 bit stream counter. HDCP transmitter assigns a distinct stream counter for each Packetized Elementary Stream (PES).
 * @param in_ctr - It is 64 bit input counter. It is initialized to zero after SKE and must not be reset ata ny other time.
 * @param input - pointer to the data to be encrypted.
 * @param inlen - length of input data.
 * @param output - pointer to the output data, that will be populated in this function.
 * @return int
 */
int HDCP2_Encrypt(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_ctr, u8 *input, int inlen, u8 *output, size_t offset);

#ifdef USE_MOBICORE
/**
 * @fn int HDCP2_Encrypt_PV(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_ctr, u8 *input, int inlen, u8 *output)
 * @brief This function encrypts the data stream whose physical address is specified
 * @param hdcp - pointer to HDCP context
 * @param str_ctr - It is 32 bit stream counter. HDCP transmitter assigns a distinct stream counter for each Packetized Elementary Stream (PES).
 * @param in_ctr - It is 64 bit input counter. It is initialized to zero after SKE and must not be reset at any other time.
 * @param input - pointer to the data to be encrypted.
 * @param inlen - length of input data.
 * @param output - pointer to the output data, that will be populated in this function.
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int HDCP2_Encrypt_PV(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_ctr, addr_s *input, int inlen, u8 *output);

/**
 * @fn int HDCP2_Encrypt_VV(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_ctr, u8 *input, int inlen, u8 *output)
 * @brief This function encrypts the data by first obtaining the physical address of the provided virtual address and passing it to HDCP2_Encrypt_PV
 * @param hdcp - pointer to HDCP context
 * @param str_ctr - It is 32 bit stream counter. HDCP transmitter assigns a distinct stream counter for each Packetized Elementary Stream (PES).
 * @param in_ctr - It is 64 bit input counter. It is initialized to zero after SKE and must not be reset at any other time.
 * @param input - pointer to the data to be encrypted.
 * @param inlen - length of input data.
 * @param output - pointer to the output data, that will be populated in this function.
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int HDCP2_Encrypt_VV(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_ctr, u8 *input, int inlen, u8 *output);
#elif defined(USE_TEEGRIS)
/**
 * @fn int HDCP2_Encrypt_PV(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_ctr, u8 *input, int inlen, u8 *output, int type)
 * @brief This function encrypts the data by first obtaining the physical address of the provided virtual address and passing it to HDCP2_Encrypt_PV
 * @param hdcp - pointer to HDCP context
 * @param str_ctr - It is 32 bit stream counter. HDCP transmitter assigns a distinct stream counter for each Packetized Elementary Stream (PES).
 * @param in_ctr - It is 64 bit input counter. It is initialized to zero after SKE and must not be reset at any other time.
 * @param input - pointer to the data to be encrypted.
 * @param inlen - length of input data.
 * @param output - pointer to the output data, that will be populated in this function.
 * @param type - encrypt function (encrypt or encryptNative)
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int HDCP2_Encrypt_PV(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_ctr, u8 *input, int inlen, u8 *output, int type);

/**
 * @fn int HDCP2_Encrypt_VV(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_ctr, u8 *input, int inlen, u8 *output, int type)
 * @brief This function encrypts the data by first obtaining the physical address of the provided virtual address and passing it to HDCP2_Encrypt_PV
 * @param hdcp - pointer to HDCP context
 * @param str_ctr - It is 32 bit stream counter. HDCP transmitter assigns a distinct stream counter for each Packetized Elementary Stream (PES).
 * @param in_ctr - It is 64 bit input counter. It is initialized to zero after SKE and must not be reset at any other time.
 * @param input - pointer to the data to be encrypted.
 * @param inlen - length of input data.
 * @param output - pointer to the output data, that will be populated in this function.
 * @param type - encrypt function (encrypt or encryptNative)
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int HDCP2_Encrypt_VV(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_ctr, u8 *input, int inlen, u8 *output, int type);
#endif

/**
 * @fn int HDCP2_Encrypt_PP(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_ctr, u8 *input, int inlen, u8 *output)
 * @brief This function encrypts the data stream whose physical address is specified
 * @param hdcp - pointer to HDCP context
 * @param str_ctr - It is 32 bit stream counter. HDCP transmitter assigns a distinct stream counter for each Packetized Elementary Stream (PES).
 * @param in_ctr - It is 64 bit input counter. It is initialized to zero after SKE and must not be reset at any other time.
 * @param input - pointer to the data to be encrypted.
 * @param inlen - length of input data.
 * @param output - pointer to the output data, that will be populated in this function.
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int HDCP2_Encrypt_PP(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_ctr, u8 *input, int inlen, u8 *output);

/**
 * @fn int HDCP2_Decrypt(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_str, u8 *input, int inlen, u8 *output)
 * @brief This function decrypts the cipher text
 * @param hdcp - pointer to HDCP context
 * @param str_ctr - It is 32 bit stream counter. HDCP transmitter assigns a distinct stream counter for each Packetized Elementary Stream (PES).
 * @param in_str - It is 64 bit input counter. It is initialized to zero after SKE and must not be reset at any other time.
 * @param input - pointer to the data to be decrypted.
 * @param inlen - length of input data.
 * @param output - pointer to the output data, that will be populated in this function.
 * @return int - returns input length in case of success else returns error values in case of failures.
 */
int HDCP2_Decrypt(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_str, u8 *input, int inlen, u8 *output);

/**
 * @fn int HDCP2_Decrypt_VP(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_str, u8 *input, int inlen, u8 *output)
 * @brief This function decrypts the data stream.
 * @param hdcp - pointer to HDCP context
 * @param str_ctr - It is 32 bit stream counter. HDCP transmitter assigns a distinct stream counter for each Packetized Elementary Stream (PES).
 * @param in_str - It is 64 bit input counter. It is initialized to zero after SKE and must not be reset at any other time.
 * @param input - pointer to the data to be decrypted.
 * @param inlen - length of input data.
 * @param output - pointer to the output data, that will be populated in this function.
 * @return int - returns input length in case of success else returns error values in case of failures.
 */
int HDCP2_Decrypt_VP(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_str, u8 *input, int inlen, u8 *output);

/**
 * @fn int HDCP2_Decrypt_VV(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_str, u8 *input, int inlen, u8 *output)
 * @brief This function decrypts the data stream.
 * @param hdcp - pointer to HDCP context
 * @param str_ctr - It is 32 bit stream counter. HDCP transmitter assigns a distinct stream counter for each Packetized Elementary Stream (PES).
 * @param in_str - It is 64 bit input counter. It is initialized to zero after SKE and must not be reset at any other time.
 * @param input - pointer to the data to be decrypted.
 * @param inlen - length of input data.
 * @param output - pointer to the output data, that will be populated in this function.
 * @return int - returns input length in case of success else returns error values in case of failures.
 */
int HDCP2_Decrypt_VV(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_str, u8 *input, int inlen, u8 *output);

/**
 * @fn int HDCP2_Decrypt_Ex_VP(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_str, u8 *input, int inlen, u8 *output, u32 dec_type, int codec_type)
 * @brief This function decrypts data stream in unsecure world.
 * @param hdcp - pointer to HDCP context
 * @param str_ctr - It is 32 bit stream counter. HDCP transmitter assigns a distinct stream counter for each Packetized Elementary Stream (PES).
 * @param in_str - It is 64 bit input counter. It is initialized to zero after SKE and must not be reset at any other time.
 * @param input - pointer to the data to be decrypted.
 * @param inlen - length of input data.
 * @param output - pointer to the output data, that will be populated in this function.
 * @param dec_type -  decrytion type
 * @param codec_type - codec type
 * @return int - returns input length in case of success else returns error values in case of failures.
 */
int HDCP2_Decrypt_Ex_VP(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_str, u8 *input, int inlen, addr_s *output, u32 dec_type, int codec_type);

#if defined(USE_QUALCOMM) || defined(USE_TEEGRIS)
/**
 * @fn int HDCP2_Decrypt_ION(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_str, u8 *input, int inlen, u32 ion_fd)
 * @brief This function decrypts the data stream in secure memory when using qualcomm chipset
 * @param hdcp - pointer to HDCP context
 * @param str_ctr - It is 32 bit stream counter. HDCP transmitter assigns a distinct stream counter for each Packetized Elementary Stream (PES).
 * @param in_str - It is 64 bit input counter. It is initialized to zero after SKE and must not be reset at any other time.
 * @param input - pointer to the data to be decrypted.
 * @param inlen - length of input data.
 * @param ion_fd- file descriptor corresponding to secure memory
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int HDCP2_Decrypt_ION(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_str, u8 *input, int inlen, u32 ion_fd);
#else
/**
 * @fn int HDCP2_Decrypt_ION(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_str, u8 *input, int inlen,uint32_t outputHandle, uint32_t outputOffset, uint32_t *outputLength)
 * @brief This function decrypts the data stream in secure memory.
 * @param hdcp - pointer to HDCP context.
 * @param str_ctr - It is 32 bit stream counter. HDCP transmitter assigns a distinct stream counter for each Packetized Elementary Stream (PES).
 * @param in_str - It is 64 bit input counter. It is initialized to zero after SKE and must not be reset at any other time.
 * @param input - pointer to the data to be decrypted.
 * @param inlen - length of input data.
 * @param outputHandle - pointer to the output buffer.
 * @param outputOffset - offset of output buffer.
 * @param outputLength - length of output buffer.
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int HDCP2_Decrypt_ION(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_str, u8 *input, int inlen,
			uint32_t outputHandle, uint32_t outputOffset, uint32_t *outputLength);
#endif /* USE_QUALCOMM || USE_TEEGRIS */

/**
 * int HDCP2_Set_AKE_RetryPolicy(HDCP2_Ctx *hdcp, long timeout, int ake_retry_count, int lc_retry_count)
 * @brief This function checks with retry policy if anymore retries for AKE_Init can be performed in case of error in connection.
 * @param hdcp - pointer to HDCP context.
 * @param timeout - Time elapsed since Ake_init was first called.
 * @param ake_retry_count - indicates the number times AKE_Init has been retried.
 * @param lc_retry_count - indicates the number of times lc_init has been retried.
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error.
 */
int HDCP2_Set_AKE_RetryPolicy(HDCP2_Ctx *hdcp, long timeout, int ake_retry_count, int lc_retry_count);

/**
 * @fn int HDCP2_SetMagicKey(HDCP2_Ctx *hdcp)
 * @brief This function is to set Magic Key in secure world(trustzone).
 * @param hdcp - pointer to HDCP context.
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error.
 */
int HDCP2_SetMagicKey(HDCP2_Ctx *hdcp);

// High level APIs - Rx
/**
 * @fn int HDCP2_IsKeyFrame(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_ctr, int codec_type, void *pes_pkt, int pes_pkt_size)
 * @brief Checks whether the received frame is a key frame
 * @param hdcp - pointer to HDCP context
 * @param str_ctr - It is 32 bit stream counter. HDCP transmitter assigns a distinct stream counter for each Packetized Elementary Stream (PES).
 * @param in_ctr - It is 64 bit input counter. It is initialized to zero after SKE and must not be reset at any other time.
 * @param codec_type codec type
 * @param pes_pkt - pointer to Packetized Elementary Stream (PES)
 * @param pes_pkt_size - size of pes_pkt
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int HDCP2_IsKeyFrame(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_ctr, int codec_type, void *pes_pkt, int pes_pkt_size);

/**
 * @fn int HDCP2_IsKeyFrame_WFD(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_ctr, int codec_type, void *pes_pkt, int pes_pkt_size)
 * @brief Checks whether the received frame is a key frame
 * @param hdcp - pointer to HDCP context
 * @param str_ctr - It is 32 bit stream counter. HDCP transmitter assigns a distinct stream counter for each Packetized Elementary Stream (PES).
 * @param in_ctr - It is 64 bit input counter. It is initialized to zero after SKE and must not be reset at any other time.
 * @param codec_type - specifies code type
 * @param pes_pkt - pointer to Packetized Elementary Stream (PES)
 * @param pes_pkt_size - size od pes_pkt
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int HDCP2_IsKeyFrame_WFD(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_ctr, int codec_type, void *pes_pkt, int pes_pkt_size);

/**
 * @fn int HDCP2_DecryptAudio(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_ctr, u8 *input, int inlen, u8 *output)
 * @brief The function is exposed to decrypt audio
 * @param hdcp - pointer to HDCP context
 * @param str_ctr - It is 32 bit stream counter. HDCP transmitter assigns a distinct stream counter for each Packetized Elementary Stream (PES).
 * @param in_ctr - It is 64 bit input counter. It is initialized to zero after SKE and must not be reset at any other time.
 * @param input - pointer to the data to be decrypted.
 * @param inlen - length of input data.
 * @param output - pointer to the output data, that will be populated in this function.
 * @return int - returns input length in case of success else returns error values in case of failures.
 */
int HDCP2_DecryptAudio(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_ctr, u8 *input, int inlen, u8 *output);

/**
 * @fn int HDCP2_DecryptVideo(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_ctr, u8 *input, int inlen, obp output)
 * @brief The function is exposed to decrypt video
 * @param hdcp - pointer to HDCP context
 * @param str_ctr - It is 32 bit stream counter. HDCP transmitter assigns a distinct stream counter for each Packetized Elementary Stream (PES).
 * @param in_ctr - It is 64 bit input counter. It is initialized to zero after SKE and must not be reset at any other time.
 * @param input - pointer to the data to be decrypted.
 * @param inlen - length of input data.
 * @param output - pointer to the output data, that will be populated in this function.
 * @return int - returns input length in case of success else returns error values in case of failures.
 */
int HDCP2_DecryptVideo(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_ctr, u8 *input, int inlen, obp output);

/**
 * @fn int HDCP2_Encrypt_Drm(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_ctr, u8 *input, int inlen, u8 *output, int type)
 * @brief The function is used to encrypt the Drm Content under the HDCP encryption protocol.
 * @param hdcp - pointer to HDCP context
 * @param str_ctr - It is 32 bit stream counter. HDCP transmitter assigns a distinct stream counter for each Packetized Elementary Stream (PES).
 * @param in_ctr - It is 64 bit input counter. It is initialized to zero after SKE and must not be reset at any other time.
 * @param input - pointer to the data to be encrypted.
 * @param inlen - length of input data.
 * @param output - pointer to the output data, that will be populated in this function.
 * @param type - determines the type of buffer i.e. TZ buffer or Normal buffer
 * @return int - returns input length in case of success else returns error values in case of failures.
 */
int HDCP2_Encrypt_Drm(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_ctr, u8 *input, int inlen, u8 *output, int type);

/**
 * @fn int HDCP2_Decrypt_Ex(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_ctr, u8 *input, int inlen, u8 *output, u32 dec_type, int codec_type)
 * @brief This function decypts the data when qualcomm chipset is used.
 * @param hdcp - pointer to HDCP context
 * @param str_ctr - It is 32 bit stream counter. HDCP transmitter assigns a distinct stream counter for each Packetized Elementary Stream (PES).
 * @param in_ctr - It is 64 bit input counter. It is initialized to zero after SKE and must not be reset at any other time.
 * @param input - pointer to the data to be decrypted.
 * @param inlen - length of input data.
 * @param output - pointer to the output data, that will be populated in this function.
 * @param dec_type -  decryption type
 * @param codec_type - Codec type
 * @return int - returns length of decrypted data in case of success, else error code corresponding to the error
 */
int HDCP2_Decrypt_Ex(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_ctr, u8 *input, int inlen, u8 *output, u32 dec_type, int codec_type);

// High level APIs - Rep
/**
 * @fn HDCP2_IsKeyFrame_Rep(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_str, int codec_type, void *pes_pkt, int pes_pkt_size)
 * @brief This function checks for Repaeaters, if the the frame received is Key frame.
 * @param hdcp - pointer to HDCP context
 * @param str_ctr - It is 32 bit stream counter. HDCP transmitter assigns a distinct stream counter for each Packetized Elementary Stream (PES).
 * @param in_str - It is 64 bit input counter. It is initialized to zero after SKE and must not be reset at any other time.
 * @param codec_type codec type
 * @param pes_pkt - pointer to Packetized Elementary Stream (PES)
 * @param pes_pkt_size - size od pes_pkt
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int HDCP2_IsKeyFrame_Rep(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_str, int codec_type, void *pes_pkt, int pes_pkt_size);

/**
 * @fn int HDCP2_DecryptAudio_Rep(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_str, u8 *input, int inlen, u8 *output)
 * @brief This function decrypts audio data stream for Repeater.
 * @param hdcp - pointer to HDCP context
 * @param str_ctr - It is 32 bit stream counter. HDCP transmitter assigns a distinct stream counter for each Packetized Elementary Stream (PES).
 * @param in_str - It is 64 bit input counter. It is initialized to zero after SKE and must not be reset at any other time.
 * @param input - pointer to the data to be decrypted.
 * @param inlen - length of input data.
 * @param output - pointer to the output data, that will be populated in this function.
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int HDCP2_DecryptAudio_Rep(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_str, u8 *input, int inlen, u8 *output);

/**
 * @fn int HDCP2_DecryptVideo_Rep(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_str, u8 *input, int inlen, obp output)
 * @brief This function decrypts video data stream for Repeater.
 * @param hdcp - pointer to HDCP context
 * @param str_ctr - It is 32 bit stream counter. HDCP transmitter assigns a distinct stream counter for each Packetized Elementary Stream (PES).
 * @param in_str - It is 64 bit input counter. It is initialized to zero after SKE and must not be reset at any other time.
 * @param input - pointer to the data to be decrypted.
 * @param inlen - length of input data.
 * @param output - pointer to the output data, that will be populated in this function.
 * @return int HDCP2_OK in case of success, else error code corresponding to the error
 */
int HDCP2_DecryptVideo_Rep(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_str, u8 *input, int inlen, obp output);

/**
 * @fn int HDCP2_SpsPpsToSecmem(HDCP2_Ctx *hdcp, u8 *sps_pps, u8 *phy_output, int inlen)
 * @brief sps_pps header is copied to secure memory
 * @param hdcp - pointer to HDCP context
 * @param sps_pps - pointer to to non-secure memory of sps_pps
 * @param output - pointer to to secure memory of sps_pps
 * @param inlen - length of input data
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int HDCP2_SpsPpsToSecmem(HDCP2_Ctx *hdcp, u8 *sps_pps, u8 *phy_output, int inlen);
int HDCP2_CopyToSecureMem_ION(HDCP2_Ctx *hdcp, u8 *input, int inlen, u32 ion_fd);

// common APIs
/**
 * @fn int HDCP2_Ion2Addr(const int ionfd, u8 **paddr, u8 **vaddr, const int length)
 * @brief This function gets the physical address of file descriptor passed and map it to virtual memory
 * @param ionfd - input file desciptor
 * @param paddr - physical address of input
 * @param vaddr - virtual address to which it is mapped
 * @param length - length of input.
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int HDCP2_Ion2Addr(const int ion_fd, addr_s **paddr, u8 **vaddr, const int length);

/**
 * @fn int HDCP2_UnmapAddrs(u8 **vaddr, const int length)
 * @brief This function unmaps the virtual address vaddr given in the argument.
 * @param vaddr - virtual address to be unmapped.
 * @param length - length of memory to be unmapped.
 * @return int - HDCP2_OK
 */
int HDCP2_UnmapAddrs(u8 **vaddr, const int length);

/**
 * @fn int HDCP2_ConvertAddrs(const int in_ion, u8 **in_paddr, u8 **in_vaddr, const int out_ion, u8 **out_paddr, u8 **out_vaddr, const int length)
 * @brief This function gets the virtual address of the given physical address by calling function HDCP2_Ion2Addr(const int ionfd, u8 **paddr, u8 **vaddr, const int length)
 * @param in_ion - pointer to input, data at physical address
 * @param in_paddr - input data physical address
 * @param in_vaddr - input data virtual address
 * @param out_ion - pointer to output, data at virtual address
 * @param out_paddr - output data physical address
 * @param out_vaddr - input data physical address
 * @param length - length of input
 * @return int - HDCP2_OK
 */
int HDCP2_ConvertAddrs(const int in_ion, addr_s **in_paddr, u8 **in_vaddr,
			const int out_ion, u8 **out_paddr, u8 **out_vaddr, const int length);

/**
 * @fn void HDCP2_LogHex(const char *title, const unsigned char *data, int length);
 * @brief prints the data in hexadecimal form into the log file
 * @param title - pointer to the title
 * @param data - pointer to the actual data to be printed in hexadecimal form
 * @param length - length of data to be printed
 * @return void
 */
void HDCP2_LogHex(const char *title, const unsigned char *data, int length);

/**
 * @fn int HDCP2_LoadPairingInfo(HDCP2_Ctx *hdcp)
 * @brief loads the pairing info from the system (/data/system/hdcp2)
 * @param hdcp - pointer to HDCP context
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int HDCP2_LoadPairingInfo(HDCP2_Ctx *hdcp);

/**
 * @fn int HDCP2_Store_Pairing_Info(HDCP2_Ctx *hdcp)
 * @brief stores the pairing info in the system (/data/system/hdcp2)
 * @param hdcp - pointer to HDCP context
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int HDCP2_Store_Pairing_Info(HDCP2_Ctx *hdcp);

/**
 * @fn int HDCP2_Remove_Pair(HDCP2_Ctx *hdcp)
 * @brief deletes pairing info and sets hdcp->is_paired=0
 * @param hdcp - pointer to HDCP context
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int HDCP2_Remove_Pair(HDCP2_Ctx *hdcp);

/**
 * @fn int HDCP2_Start_Receiver(HDCP2_Ctx *hdcp, const int port, int threadwait);
 * @brief starts the worker thread. Worker thread handles authentication
 * @param hdcp - pointer to HDCP context
 * @param port - indicates the port to be used in establishing socket connection
 * @param threadwait If threadwait is enabled, hdcp2_start_receiver will wait for the worker thread to exit
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int HDCP2_Start_Receiver(HDCP2_Ctx *hdcp, const int port, int threadwait);

/**
 * @fn int HDCP2_Stop_Receiver(HDCP2_Ctx *hdcp)
 * @brief calls This function releases all the memory and signals the worker thread to exit
 * @param hdcp - pointer to HDCP context
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int HDCP2_Stop_Receiver(HDCP2_Ctx *hdcp);

/**
 * @fn void HDCP2_Log(const char* format, ...)
 * @brief prints the data into the log file
 * @param format pointer to data that needs to be logged
 * @return void
 */
void HDCP2_Log(const char* format, ...);

/**
 * @fn int HDCP2_HW_Init(HDCP2_Ctx *hdcp)
 * @brief This function gets crypto device lock, initializes the secure memory and sets the hdcp2 flag by initializing the trustzone
 * @param hdcp - pointer to HDCP context
 * @return int - HDCP2_OK if success else returns corresponding error code.
 */
int HDCP2_HW_Init(HDCP2_Ctx *hdcp);

/**
 * @fn int HDCP2_HW_Close(HDCP2_Ctx *hdcp)
 * @brief This function closes the trustzone, releases the secure memory and  the crypto device lock.
 * @param hdcp - pointer to HDCP context.
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error.
 */
int HDCP2_HW_Close(HDCP2_Ctx *hdcp);

/**
 * @fn int HDCP2_TZ_Open(HDCP2_Ctx *hdcp, const int entity)
 * @brief This function opens session with the Trustlet by acquiring the required resources
 * @param hdcp - pointer to HDCP context
 * @param entity - specifies if the devices is a transmitter or receiver or a repeater.
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error.
 */
int HDCP2_TZ_Open(HDCP2_Ctx *hdcp, const int entity);

/**
 * @fn void HDCP2_TZ_Close(HDCP2_Ctx *hdcp)
 * @brief It closes the connection and releases the resources
 * @param hdcp - pointer to HDCP context
 * @return void
 */
void HDCP2_TZ_Close(HDCP2_Ctx *hdcp);

/**
 * @fn int HDCP2_TZ_Reset(HDCP2_Ctx *hdcp)
 * @brief This function resets the trustzone
 * @param hdcp - pointer to HDCP context
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int HDCP2_TZ_Reset(HDCP2_Ctx *hdcp);

/**
 * @fn int HDCP2_LoadKey(HDCP2_Ctx *hdcp)
 * @brief This function loads the key
 * @param hdcp - pointer to HDCP context
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int HDCP2_LoadKey(HDCP2_Ctx *hdcp);

/**
 * @fn int HDCP2_IsClosed(HDCP2_Ctx *hdcp)
 * @brief checks if hdcp is opened or closed
 * @param hdcp - pointer to HDCP context
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int HDCP2_IsClosed(HDCP2_Ctx *hdcp);

/**
 * int HDCP2_SetVersion(HDCP2_Ctx *hdcp)
 * @brief This function update the version of HDCP.
 * @param hdcp - pointer to HDCP context.
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error.
 */
int HDCP2_SetVersion(HDCP2_Ctx *hdcp);

/**
 * @fn int HDCP2_Pause(HDCP2_Ctx *hdcp)
 * @brief This function resets the trustzone
 * @param hdcp - pointer to HDCP context
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int HDCP2_Pause(HDCP2_Ctx *hdcp);

/**
 * @fn int HDCP2_Get_Repeater_Downstream_Status(HDCP2_Ctx *hdcp, u8 *repeater20, u8 *receiver1x)
 * @brief gets the status for downstream propagation in repeater
 * @param hdcp - pointer to HDCP context
 * @param repeater20 - pointer to  info that whether a repeater is connected downstream and 2.0 repeater
 * @param receiver1x - pointer to  info that whether a repeater is connected downstream and 1.x rx device
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int HDCP2_Get_Repeater_Downstream_Status(HDCP2_Ctx *hdcp, u8 *repeater20, u8 *receiver1x);

/**
 * @fn void HDCP2_Close_Socket(HDCP2_Ctx *hdcp, const char *type)
 * @brief closes the socket connection between transmitter and receiver/repeater
 * @param hdcp - pointer to HDCP context
 * @param type - pointer to csd/sd
 * @return void
 */
void HDCP2_Close_Socket(HDCP2_Ctx *hdcp, const char *type);

/**
 * @fn int AKE_Init_T(HDCP2_Ctx *hdcp, u8 *payload)
 * @brief This function initiates the authentication from transmitter by sending the initiation message which contains 64 bit pseudo random value
 * @param hdcp - pointer to HDCP context
 * @param payload - pointer to the buffer containing  AKE_INIT message to be sent to receiver
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int AKE_Init_T(HDCP2_Ctx *hdcp, u8 *payload);

/**
 * @fn int AKE_Tramsmitter_Info_T(HDCP2_Ctx *hdcp, u8 *payload);
 * @brief This function sends the transmitter info to the receiver
 * @param hdcp - pointer to HDCP context
 * @param payload - pointer to the buffer containing  AKE_TRANSMITTER_INFO message to be sent to receiver
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int AKE_Tramsmitter_Info_T(HDCP2_Ctx *hdcp, u8 *payload);

/**
 * @fn int AKE_Send_Cert_T(HDCP2_Ctx *hdcp, u8 *payload, u8 *received);
 * @brief A certificate is  received from the receiver which indicates whether the connected receiver is an HDCP receiver and also extracts Receiver ID
 * @param hdcp - pointer to HDCP context
 * @param payload - pointer to the buffer which is populated in transmitter, but here it is not being used and thus is always assigned NULL
 * @param received - pointer to the buffer containing AKE_SEND_CERT message
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int AKE_Send_Cert_T(HDCP2_Ctx *hdcp, u8 *payload, u8 *received);
/**
 * @fn int AKE_Receiver_Info_T(HDCP2_Ctx *hdcp, u8 *received)
 * @brief This function contains the information regarding compliance of receiver with various hdcp versions
 * @param hdcp - pointer to HDCP context
 * @param received - pointer to the buffer containing AKE_RECEIVER_INFO message received from receiver
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int AKE_Receiver_Info_T(HDCP2_Ctx *hdcp, u8 *received);

/**
 * @fn int AKE_No_Stored_km_T(HDCP2_Ctx *hdcp, u8 *payload)
 * @brief This function is called when transmitter does not have 128 bit master key stored corresponding to the receiver ID.
 * @param hdcp - pointer to HDCP context
 * @param payload - pointer to the buffer containing AKE_NO_STORED_KM message
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int AKE_No_Stored_km_T(HDCP2_Ctx *hdcp, u8 *payload);

/**
 * @fn int AKE_Stored_km_T(HDCP2_Ctx *hdcp, u8 *payload)
 * @brief This function is called when transmitter has 128 bit master key corresponding to the receiver ID.
 *  Here AKE_Stored_km message is sent to receiver with 128 bit encrypted master key and 128 bit  corresponding to the Receiver ID of the receiver.
 * @param hdcp - pointer to HDCP context
 * @param payload - pointer to the buffer containing AKE_STORED_KM message
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int AKE_Stored_km_T(HDCP2_Ctx *hdcp, u8 *payload);

/**
 * @fn int AKE_Send_rrx_T(HDCP2_Ctx *hdcp, u8 *received)
 * @brief This function receives AKE_Send_rrx message from receiver containing the 64 bit pseudo random value
 * @param hdcp - pointer to HDCP context
 * @param received - pointer to the buffer containing AKE_SEND_RRX message received from receiver
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int AKE_Send_rrx_T(HDCP2_Ctx *hdcp, u8 *received);

/**
 * @fn int AKE_Send_H_prime_T(HDCP2_Ctx *hdcp, u8 *received)
 * @brief This function receives AKE_SEND_H_PRIME message from the receiver which contains 256-bit H-prime. This message has to be received within 200ms in case of stored_km and within 1s in case of no_stored_km.
 * @param hdcp - pointer to HDCP context
 * @param received - pointer to the buffer containing AKE_SEND_H_PRIME message received from the receiver.
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int AKE_Send_H_prime_T(HDCP2_Ctx *hdcp, u8 *received);

/**
 * @fn int AKE_Send_Pairing_Info_T(HDCP2_Ctx *hdcp, u8 *received)
 * @brief This function receives AKE_SEND_PAIRING_INFO message from receiverwhich contains 128 bit Ekh(km).
 * @param hdcp - pointer to HDCP context
 * @param received - pointer to to the buffer containing AKE_SEND_PAIRING_INFO message received from the receiver.
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int AKE_Send_Pairing_Info_T(HDCP2_Ctx *hdcp, u8 *received);

/**
 * @fn int LC_Init_T(HDCP2_Ctx *hdcp, u8 *payload)
 * @brief This function initiates locality check by sending a message containing 64 bit pseudo random number to hdcp receiver
 * @param hdcp - pointer to HDCP context
 * @param payload - pointer to the buffer containing LC_INIT message to be sent
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int LC_Init_T(HDCP2_Ctx *hdcp, u8 *payload);

/**
 * @fn int RTT_Ready_T(HDCP2_Ctx *hdcp, u8 *received);
 * @brief This functions function receives the message when receiver is ready to send L-prime
 * @param hdcp - pointer to HDCP context
 * @param received - pointer to buffer containg RTT_READY message received from the receiver.
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int RTT_Ready_T(HDCP2_Ctx *hdcp, u8 *received);

/**
 * @fn int RTT_Challenge_T(HDCP2_Ctx *hdcp, u8 *payload);
 * @brief This function sends the message containing the least significant 128 bits of L to the receiver
 * @param hdcp - pointer to HDCP context
 * @param payload - pointer to the buffer containing RTT_CHALLENGE message
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int RTT_Challenge_T(HDCP2_Ctx *hdcp, u8 *payload);

/**
 * @fn int LC_Send_L_prime_T(HDCP2_Ctx *hdcp, u8 *received)
 * @brief This function receives a message containing most significant bits of L- prime from receiver. This is compared with L. The time elapsed between sending RTT_Challenge_T and receiving L-prime must be less than 7ms.
 * @param hdcp - pointer to HDCP context
 * @param received - pointer to buffer containing LC_SEND_L_PRIME message received from the receiver.
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int LC_Send_L_prime_T(HDCP2_Ctx *hdcp, u8 *received);

/**
 * @fn int SKE_Send_Eks_T(HDCP2_Ctx *hdcp, u8 *payload)
 * @brief This function sends a message containing Edkey(ks) and a 64 bit pseudo random number to the hdcp receiver
 * @param hdcp - pointer to HDCP context
 * @param payload - pointer to SKE_SEND_EKS message sent to receiver
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int SKE_Send_Eks_T(HDCP2_Ctx *hdcp, u8 *payload);

/**
 * @fn int HDCP2_SRM_Check(u8 *receiverID, u8 device_count)
 * @brief This function checks if the receiver ID is blacklisted
 * @param receiverID - pointer to receiver ID
 * @param device_count - no. of devices
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int HDCP2_SRM_Check(u8 *receiverID, u8 device_count);

//Tx-Repeater Support
/**
 * @fn nt RepeaterAuth_Send_ReceiverId_List_T(HDCP2_Ctx *hdcp, u8 *received)
 * @brief This function gets the message containing the information regarding the receivers connected to the repeater
 * @param hdcp - pointer to HDCP context
 * @param received - pointer to the REPEATERAUTH_SEND_RECEIVER_ID_LIST21 message received by the transmitter
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int RepeaterAuth_Send_ReceiverId_List_T(HDCP2_Ctx *hdcp, u8 *received);

/**
 * @fn int RepeaterAuth_Send_Ack_T(HDCP2_Ctx *hdcp, u8 *payload)
 * @brief This function sends an acknowledgment to the receiver
 * @param hdcp - pointer to HDCP context
 * @param payload - pointer to  REPEATERAUTH_SEND_ACK message that is sent by the transmitter as an acknowledgment to REPEATERAUTH_SEND_RECEIVER_ID_LIST21 received in the previous message.
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int RepeaterAuth_Send_Ack_T(HDCP2_Ctx *hdcp, u8 *payload);

/**
 * @fn int Receiver_AuthStatus_T(HDCP2_Ctx *hdcp, u8 *received)
 * @brief This function lets the transmitter know about the authentication status of receiver with the repeater
 * @param hdcp - pointer to HDCP context
 * @param received - pointer to RECEIVER_AUTHSTATUS message received by the transmitter
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int Receiver_AuthStatus_T(HDCP2_Ctx *hdcp, u8 *received);

/**
 * @fn int RepeaterAuth_Stream_Manage_T(HDCP2_Ctx *hdcp, u8 *payload, Downstream_Params *params)
 * @brief This function propagates content stream management information, which includes Type values assigned to the content streams
 * @param hdcp - pointer to HDCP context
 * @param payload - pointer to REPEATERAUTH_STREAM_MANAGE message to be sent from transmitter
 * @param params pointer to structure Downstream_Params
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int RepeaterAuth_Stream_Manage_T(HDCP2_Ctx *hdcp, u8 *payload, Downstream_Params *params);

/**
 * @fn int RepeaterAuth_Stream_Ready_T(HDCP2_Ctx *hdcp, u8 *received)
 * @brief This function obtains M- prime as sent by repeater
 * @param hdcp - pointer to HDCP context
 * @param received - pointer to REPEATERAUTH_STREAM_READY message received by the transmitter
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int RepeaterAuth_Stream_Ready_T(HDCP2_Ctx *hdcp, u8 *received);

/**
 * @fn int HDCP2_DownstreamPropagation(HDCP2_Ctx *hdcp, Downstream_Params *params, int k)
 * @brief This function sends RepeaterAuth stream manage massage to transmitter, sets timeout for RepeaterAuth_Stream_Ready, receives RepeaterAuth stream ready  message and checks timeout for RepeaterAuth_Stream_Ready
 * @param hdcp - pointer to HDCP context.
 * @param params - pointer to structure Downstream_Params.
 * @param int k - maximum number of streams possible.
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error.
 */
int HDCP2_DownstreamPropagation(HDCP2_Ctx *hdcp, Downstream_Params *params, int k);

/**
 * @fn int HDCP2_Get_RegiDescriptor(u8 *received)
 * @brief This function gets the register descriptor
 * @param - pointer to the object received.
 * @return int
 */
int HDCP2_Get_RegiDescriptor(u8 *received);

/**
 * @fn int AKE_Init_R(HDCP2_Ctx *hdcp, u8 *received)
 * @brief This function Copies rtx sent by transmitter to the TZ HDCP Context.
 * @param hdcp - pointer to HDCP context.
 * @param received - Pointer to AKE init Object which contains message ID, rtx.
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error.
 */
int AKE_Init_R(HDCP2_Ctx *hdcp, u8 *received);

/**
 * @fn int AKE_Tramsmitter_Info_R(HDCP2_Ctx *hdcp, u8 *received)
 * @brief This function Copies transmitter info received into TZ HDCP Context.
 * @param hdcp - pointer to HDCP context
 * @param received - Pointer to Transmitter info Object which contains message ID, Lenght,Version,and Transmitter Capability mask
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int AKE_Tramsmitter_Info_R(HDCP2_Ctx *hdcp, u8 *payload);

/**
 * @fn int AKE_Send_Cert_R(HDCP2_Ctx *hdcp, u8 *payload)
 * @brief This function Copies and sends receiver certificate to transmitter.
 * @param hdcp - pointer to HDCP context.
 * @param payload - Pointer to Receiver Certificate object which contains msg ID Repeater flag and receiver certificate.
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error.
 */
int AKE_Send_Cert_R(HDCP2_Ctx *hdcp, u8 *payload);

/**
 * @fn int AKE_Receiver_Info_R(HDCP2_Ctx *hdcp, u8 *payload)
 * @brief This function Forms receiver information and send it to transmitter.
 * @param hdcp - pointer to HDCP context
 * @param payload - Pointer to Receiver info Object which contains message ID, Lenght,Version,and Receiver Capability mask
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int AKE_Receiver_Info_R(HDCP2_Ctx *hdcp, u8 *received);

/**
 * @fn int AKE_No_Stored_km_R(HDCP2_Ctx *hdcp, u8 *received)
 * @brief This function Receives Ekpub_km from transmitter and Decrypts it to get km using RSA_OAEP_decrypt and copies it to the TZ HDCP Context
 * @param hdcp - pointer to HDCP context
 * @param received - Pointer to No stored Km Object which contains message ID and 128 bytes of Encrypted km[Ekpub_km] from transmitter
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int AKE_No_Stored_km_R(HDCP2_Ctx *hdcp, u8 *payload);

/**
 * @fn int AKE_Stored_km_R(HDCP2_Ctx *hdcp, u8 *received)
 * @brief This function Receives Ekh_km from transmitter and Decrypts it to get km and copies it to the TZ HDCP Context
 * @param hdcp - pointer to HDCP context
 * @param received - Pointer to stored Km Object which contains message ID and 128 bytes of Encrypted km[Ekh_km] from transmitter
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int AKE_Stored_km_R(HDCP2_Ctx *hdcp, u8 *payload);

/**
 * @fn int AKE_Send_rrx_R(HDCP2_Ctx *hdcp, u8 *payload)
 * @brief This function Generates and sends 8bytes of random number[rrx] to transmitter.
 * @param hdcp - pointer to HDCP context
 * @param payload - Pointer to rrx  Object which contains message ID and 8bytes of rrx
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int AKE_Send_rrx_R(HDCP2_Ctx *hdcp, u8 *payload);

/**
 * @fn int AKE_Send_H_prime_R(HDCP2_Ctx *hdcp, u8 *payload)
 * @brief This function Generates H prime and send it to the transmitter as below eqn.
 * @param hdcp - pointer to HDCP context
 * @param payload - Pointer to H prime Object which contains message ID and H prime
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int AKE_Send_H_prime_R(HDCP2_Ctx *hdcp, u8 *payload);

/**
 * @fn int AKE_Send_Pairing_Info_R(HDCP2_Ctx *hdcp, u8 *payload)
 * @brief This function Generates Ekh_km and send it to the transmitter.
 * @param hdcp - pointer to HDCP context.
 * @param payload - Pointer to pairing info Object which contains message ID and Ekh_km.
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error.
 */
int AKE_Send_Pairing_Info_R(HDCP2_Ctx *hdcp, u8 *payload);

/**
 * @fn int LC_Init_R(HDCP2_Ctx *hdcp, u8 *received)
 * @brief This function Copies received random value [rn] from transmitter.
 * @param hdcp - pointer to HDCP context.
 * @param received - Pointer to Lc Init Object which contains message ID and random number sent by the transmitter.
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error.
 */
int LC_Init_R(HDCP2_Ctx *hdcp, u8 *received);

/**
 * @fn int RTT_Ready_R(HDCP2_Ctx *hdcp, u8 *payload)
 * @brief This function sends RTT_Ready message to transmitter when L' computation is complete.
 * @param hdcp - pointer to HDCP context
 * @param payload - pointer to RTT_READY object which contains message ID.
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int RTT_Ready_R(HDCP2_Ctx *hdcp, u8 *payload);

/**
 * @fn int RTT_Challenge_R(HDCP2_Ctx *hdcp, u8 *received)
 * @brief This function copies received least significant 128 bits of L from transmitter.
 * @param hdcp - pointer to HDCP context
 * @param received - pointer to RTT_CHALLENGE object which contains message ID and 128 lsb of L.
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int RTT_Challenge_R(HDCP2_Ctx *hdcp, u8 *received);

/**
 * @fn int LC_Send_L_prime_R(HDCP2_Ctx *hdcp, u8 *payload)
 * @brief This function calaculates L by equation : HMAC_SHA256(rn, (kd ^ rrx) )
 * @param hdcp - pointer to HDCP context
 * @param payload - Pointer to L Prime Object which contains message ID and memory to place L value.
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int LC_Send_L_prime_R(HDCP2_Ctx *hdcp, u8 *payload);

/**
 * @fn int SKE_Send_Eks_R(HDCP2_Ctx *hdcp, u8 *received)
 * @brief This function decrypts Eks using riv
 * @param hdcp - pointer to HDCP context
 * @param received - Pointer to Eks Object which contains message ID, Eks and riv
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int SKE_Send_Eks_R(HDCP2_Ctx *hdcp, u8 *received);

/**
 * @fn int HDCP2_Decrypt_Ex_IsKeyFrame(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_str, u8 *input, int inlen, u8 *output, u32 dec_type, int codec_type)
 * @brief Checks whether the received frame is a key frame.
 * @param hdcp - pointer to HDCP context
 * @param str_ctr - It is 32 bit stream counter. HDCP transmitter assigns a distinct stream counter for each Packetized Elementary Stream (PES).
 * @param in_str - It is 64 bit input counter. It is initialized to zero after SKE and must not be reset at any other time.
 * @param input - pointer to the data to be decrypted.
 * @param inlen - length of input data.
 * @param output - pointer to the output data, that will be populated in this function.
 * @param dec_type -  Decryption type
 * @param codec_type - Codec type
 * @return int - returns input length in case of success else returns error values in case of failures.
 */
int HDCP2_Decrypt_Ex_IsKeyFrame(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_str,
			u8 *input, int inlen, u8 *output, u32 dec_type, int codec_type);

/**
 * @fn int HDCP2_Decrypt_Ex_Audio(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_str, u8 *input, int inlen, u8 *output, u32 dec_type, int codec_type)
 * @brief Decrypts the audio data stream
 * @param hdcp - pointer to HDCP context
 * @param str_ctr - It is 32 bit stream counter. HDCP transmitter assigns a distinct stream counter for each Packetized Elementary Stream (PES).
 * @param in_str - It is 64 bit input counter. It is initialized to zero after SKE and must not be reset at any other time.
 * @param input - pointer to the data to be decrypted.
 * @param inlen - length of input data.
 * @param output - pointer to the output data, that will be populated in this function.
 * @param dec_type -  Decryption type
 * @param codec_type - Codec type
 * @return int - returns input length in case of success else returns error values in case of failures.
 */
int HDCP2_Decrypt_Ex_Audio(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_str, u8 *input,
			int inlen, u8 *output, u32 dec_type, int codec_type);

/**
 * @fn int HDCP2_Decrypt_Ex_VP(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_str, u8 *input, int inlen, u8 *output, u32 dec_type, int codec_type)
 * @brief This function decrypts data stream in unsecure world.
 * @param hdcp - pointer to HDCP context
 * @param str_ctr - It is 32 bit stream counter. HDCP transmitter assigns a distinct stream counter for each Packetized Elementary Stream (PES).
 * @param in_str - It is 64 bit input counter. It is initialized to zero after SKE and must not be reset at any other time.
 * @param input - pointer to the data to be decrypted.
 * @param inlen - length of input data.
 * @param output - pointer to the output data, that will be populated in this function.
 * @param dec_type -  decrytion type
 * @param codec_type - codec type
 * @return int - returns input length in case of success else returns error values in case of failures.
 */
int HDCP2_Decrypt_Ex_VP(HDCP2_Ctx *hdcp, u32 str_ctr, u64 in_str, u8 *input,
			int inlen, addr_s *output, u32 dec_type, int codec_type);

/**
 * @fn nt RepeaterAuth_Send_ReceiverId_List_Rep(HDCP2_Ctx *hdcp, u8 *payload)
 * @brief This function sends the message containing the information regarding the receivers connected to the repeater
 * @param hdcp - pointer to HDCP context
 * @param received - pointer to the REPEATERAUTH_SEND_RECEIVER_ID_LIST21 message send by the repeater
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int RepeaterAuth_Send_ReceiverId_List_Rep(HDCP2_Ctx *hdcp, u8 *payload);

/**
 * @fn int RepeaterAuth_Send_Ack_Rep(HDCP2_Ctx *hdcp, u8 *received)
 * @brief This function receives an acknowledgment from the transmitter
 * @param hdcp - pointer to HDCP context
 * @param received - pointer to  REPEATERAUTH_SEND_ACK message that is sent by the transmitter as an acknowledgment to REPEATERAUTH_SEND_RECEIVER_ID_LIST21 sent in the previous message.
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int RepeaterAuth_Send_Ack_Rep(HDCP2_Ctx *hdcp, u8 *received);

/**
 * @fn int Receiver_AuthStatus_Rep(HDCP2_Ctx *hdcp, u8 *payload)
 * @brief This function lets the transmitter know about the authentication status of receiver with the repeater
 * @param hdcp - pointer to HDCP context
 * @param payload - pointer to RECEIVER_AUTHSTATUS message sent by the repeater
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int Receiver_AuthStatus_Rep(HDCP2_Ctx *hdcp, u8 *payload);

/**
 * @fn int RepeaterAuth_Stream_Manage_Rep(HDCP2_Ctx *hdcp, u8 *received)
 * @brief This function propagates content stream management information, which includes Type values assigned to the content streams
 * @param hdcp - pointer to HDCP context
 * @param received - pointer to REPEATERAUTH_STREAM_MANAGE message received by the repeater
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int RepeaterAuth_Stream_Manage_Rep(HDCP2_Ctx *hdcp, u8 *received);

/**
 * @fn int RepeaterAuth_Stream_Ready_Rep(HDCP2_Ctx *hdcp, u8 *payload)
 * @brief This function sends M- prime to the transmitter
 * @param hdcp - pointer to HDCP context
 * @param payload - pointer to REPEATERAUTH_STREAM_READY message sent by the transmitter
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int RepeaterAuth_Stream_Ready_Rep(HDCP2_Ctx *hdcp, u8 *payload);

/**
 * @fn int HDCP2_Start_Repeater(HDCP2_Ctx *hdcp, const int port, HDCP2Observer observerNotify, void* wfd_ctx)
 * @brief This function calls HDCP2_Start_WFD_Receiver function which creates a socket and also creates threads of repeater worker type
 * @param hdcp - pointer to HDCP context
 * @param observerNotify - Callback function which is to be defined in WFD for error handling
 * @param wfd_ctx - pointer to WFD context
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int HDCP2_Start_Repeater(HDCP2_Ctx *hdcp, const int port, HDCP2Observer observerNotify, void* wfd_ctx);

/**
 * @fn int HDCP2_Stop_Repeater(HDCP2_Ctx *hdcp)
 * @brief This function closes the socket connection
 * @param hdcp - pointer to HDCP context
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int HDCP2_Stop_Repeater(HDCP2_Ctx *hdcp);

/**
 * @fn int HDCP2_Start_WFD_Receiver(HDCP2_Ctx *hdcp, const int port, HDCP2Observer observerNotify, void* wfd_ctx)
 * @brief This function  which creates a socket and also creates threads of repeater worker type
 * @param hdcp - pointer to HDCP context
 * @param port - port on which socket will be created
 * @param observerNotify - Callback function which is to be defined in WFD for error handling
 */
int HDCP2_Start_WFD_Receiver(HDCP2_Ctx *hdcp, const int port, HDCP2Observer observerNotify, void* wfd_ctx);

/**
 * @fn int HDCP2_Stop_WFD_Receiver(HDCP2_Ctx *hdcp)
 * @brief This function closes the socket connection by calling HDCP2_Stop_Repeater function
 * @param hdcp - pointer to HDCP context
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int HDCP2_Stop_WFD_Receiver(HDCP2_Ctx *hdcp);

/**
 * @fn int HDCP2_StoreContentKey(HDCP2_Ctx *hdcp)
 * @brief This function stores the content key.
 * @param hdcp - pointer to HDCP context
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int HDCP2_StoreContentKey(HDCP2_Ctx *hdcp);

/**
 * @fn int HDCP2_DeleteContentKey(HDCP2_Ctx *hdcp)
 * @brief This function deletes the content key.
 * @param hdcp - pointer to HDCP context
 * @return int - HDCP2_OK in case of success, else error code corresponding to the error
 */
int HDCP2_DeleteContentKey(HDCP2_Ctx *hdcp);

#ifdef USE_TEEGRIS
/** for ONLY TEEGRIS
 * @fn void HDCP2_TZ_Release_Resmem(void)
 * @brief This function release shared Response memory.
 * @return void
 */
void HDCP2_TZ_Release_Resmem();
#endif /* USE_TEEGRIS */

#ifdef __cplusplus
}
#endif

#endif /* !HDCP2_H_ */
