/**
 * @file hv_mw_Hdcp.h
 * @brief Header file of Mw module.
 *
 * @verbatim
 * ==============================================================================
 *                        ##### How to use #####
 * ==============================================================================
 * (+) Use Hv_Mw_DpHdcpEventHandler(...) Check Dp Hdcp event from Irq.
 * (+) Use Hv_Mw_HdmiHdcpEventHandler(...) Check Hdmi Hdcp event from Irq
 * (+) Use Hv_Mw_RunHdmiHdcpRxFsm(...) Run Hdcp Fsm State Machine For Hdmi.
 * (+) Use Hv_Mw_RunDpHdcpRxFsm(...) Run Hdcp Fsm State Machine For Dp.
 * (+) Use Hv_Mw_SetHdcpVersion(...) Set Hdcp Version.
 * (+) Use Hv_Mw_Hdcp1x_RunHdmiRxFsm(...) Run Hdcp1x Fsm State Machine For Hdmi.
 * (+) Use Hv_Mw_Hdcp2x_RunHdmiRxFsm(...) Run Hdcp2x Fsm State Machine For Hdmi.
 * (+) Use Hv_Mw_Hdcp1x_RunDpRxFsm(...) Run Hdcp1x Fsm State Machine For Dp.
 * (+) Use Hv_Mw_Hdcp2x_RunDpRxFsm(...) Run Hdcp2x Fsm State Machine For Dp.
 *
 * @endverbatim
 *
 * @author HiView SoC Software Team
 * @version 1.0.0
 * @date 2022-08-30
 */


#ifndef __SDK_MIDDLEWARE_HDCP_INC_HDCP_H__
#define __SDK_MIDDLEWARE_HDCP_INC_HDCP_H__

#include "hv_drv_HdcpRx.h"
#include "hv_mw_InputPortManager.h"
#include "hv_comm_Event.h"
#include "hv_comm_SafeQueue.h"
#include "hv_hdcp_Engine.h"
#include "hv_drv_Hdcp1xRx.h"
#include "hv_drv_Hdcp2xRx.h"

typedef enum _HdcpPortIndex
{
    HDCP_PORT_INDEX_RX0         = 0,
    HDCP_PORT_INDEX_RX1         = 1,
    HDCP_PORT_INDEX_INVALID     = 0xFF
}HdcpPortIndex;

/* Define Hdcp2x State Machine Srtuct*/
typedef struct _Hdcp2xRxStateMachine
{
    HdcpPort2xState enCurState;
    HdcpRxEvtId enEvtId;
    Status (*pfEvtHandler)(HdcpCtrlData* pstHdcpData);
    HdcpPort2xState enNxtSucState;
    HdcpPort2xState enNxtFailState;
}Hdcp2xRxStateMachine;

extern VOID Hv_Comm_SetHotfixRegister(UCHAR8 ucMain, UCHAR8 ucSub);

/**
 * @brief Check Dp Hdcp event from Irq.
 * @param[in] uiHdcpRxEvt: Hdcp Event.
 * @param[in] ucPortIndex: Port index.
 * @return Status, 0-HV_SUCCESS, 1-HV_FAILURE..
 */
Status  Hv_Mw_DpHdcpEventHandler(HdcpRxEvtId uiHdcpRxEvt, UCHAR8 ucPortIndex);

/**
 * @brief Check Hdmi Hdcp event from Irq.
 * @param[in] uiHdcpRxEvt: Hdcp Event.
 * @param[in] ucPortIndex: Port index.
 * @return Status, 0-HV_SUCCESS, 1-HV_FAILURE..
 */
Status  Hv_Mw_HdmiHdcpEventHandler(HdcpRxEvtId uiHdcpRxEvt, UCHAR8 ucPortIndex);

/**
 * @brief Run Hdcp Fsm State Machine For Hdmi.
 * @param[in] uiHdcpRxEvt: Hdcp Event.
 * @param[in] ucPortIndex: Port index.
 * @return None.
 */
VOID Hv_Mw_RunHdmiHdcpRxFsm(HdcpRxEvtId uiHdcpRxEvt, UCHAR8 ucPortIndex);

/**
 * @brief Run Hdcp Fsm State Machine For Dp.
 * @param[in] uiHdcpRxEvt: Hdcp Event.
 * @param[in] ucPortIndex: Port index.
 * @return None.
 */
VOID Hv_Mw_RunDpHdcpRxFsm(HdcpRxEvtId uiHdcpRxEvt, UCHAR8 ucPortIndex);


/**
 * @brief Run Hdcp2x Fsm State Machine For Hdmi.
 * @param[in] uiHdcpRxEvt: Hdcp Event.
 * @param[in] ucPortIndex: Port index.
 * @return VOID.
 */
VOID Hv_Mw_Hdcp2x_RunHdmiRxFsm(HdcpRxEvtId uiHdcpRxEvt, HdcpCtrlData* pstHdcpData);


/**
 * @brief Run Hdcp1x Fsm State Machine For Dp.
 * @param[in] uiHdcpRxEvt: Hdcp Event.
 * @param[in] ucPortIndex: Port index.
 * @return Status, 0-HV_SUCCESS, 1-HV_FAILURE..
 */
Status Hv_Mw_Hdcp1x_RunDpRxFsm(HdcpRxEvtId uiHdcpRxEvt, UCHAR8 ucPortIndex);

/**
 * @brief Run Hdcp2x Fsm State Machine For Dp.
 * @param[in] uiHdcpRxEvt: Hdcp Event.
 * @param[in] ucPortIndex: Port index.
 * @return Status, 0-HV_SUCCESS, 1-HV_FAILURE.
 */
Status Hv_Mw_Hdcp2x_RunDpRxFsm(HdcpRxEvtId uiHdcpRxEvt, HdcpCtrlData* pstHdcpData);

/**
 * @brief Hdcp Module Init Fucntion.
 * @param[in] None.
 * @return Status, 0-HV_SUCCESS, 1-HV_FAILURE..
 */
Status Hv_Mw_Hdcp_Init(HDCPManager* pstHdcpManager);

Status Hv_Mw_DpRx_HpdToggle(LinkPortIndex enPortIndex);

/**
 * @brief Set Hdcp Task Process Flag.
 * @param[in] bProcFlag: HV_TRUE -- Active Task, HV_FALSE -- Not Active Task.
 * @return None.
 */
VOID Hv_Mw_Hdcp_SetProcFlag(BOOL bProcFlag);

/**
 * @brief Get Hdcp Task Process Flag.
 * @param[in] None.
 * @return Hdcp Process Flag.
 */
BOOL Hv_Mw_Hdcp_GetProcFlag(VOID);

/**
 * @brief Process Hdcp DP Event Msg.
 * @param[in] pstHdcpQueue: Hdcp Queue.
 * @return None.
 */
//VOID Hv_Mw_Hdcp_ProcHdcpMessage(HV_VOS_QUEUE_S* pstHdcpQueue);
VOID Hv_Mw_Hdcp_ProcDpHdcpMessage(const UrgentEvent *pstUrgentEvent);

/**
 * @brief Process Hdcp HDMI Event Msg.
 * @param[in] pstHdcpQueue: Hdcp Queue.
 * @return None.
 */
VOID Hv_Mw_Hdcp_ProcHdmiHdcpMessage(const UrgentEvent *pstUrgentEvent);

/**
 * @brief Send Hdcp Event to UrgentTask.
 * @param[in] puiHdcpIntFlag: Hdcp IRQ Mask.
 * @param[in] ucPortId: Port Index.
 * @return Status, 0-HV_SUCCESS, 1-HV_FAILURE..
 */
Status Hv_Mw_Hdcp_RxISRSndEvent(UINT32 uiHdcpIntFlag, USHORT16 usPortId, UrgentRevEventType enUrgEventType);

/**
 * @brief Hdcp Set Port Mask.
 * @param[in] enPortIndex: Port index.
 * @param[in] uiHdcpWorkStat: Work Status.
 * @return Status, 0-HV_SUCCESS, 1-HV_FAILURE..
 */
Status Hv_Mw_Hdcp_DpIsrHandler(UINT32 uiIrqMask);

/**
 * @brief Hdcp Rm Port Mask.
 * @param[in] enPortIndex: Port index.
 * @param[in] uiHdcpWorkStat: Work Status.
 * @return Status, 0-HV_SUCCESS, 1-HV_FAILURE..
 */
Status Hv_Mw_Hdcp_SetHdmiRxData(HdcpCtrlData* pstHdcpData, LinkPortIndex enInputPortIndex, UCHAR8 ucHdmiPortIndex);

/**
 * @brief Get ReAuth Status.
 * @param[in] enPortIndex: Port index.
 * @return UCHAR8.
 */
UCHAR8 Hv_Mw_Hdcp_HdmiGetReAuthStatus(LinkPortIndex enInputPortIndex);

/**
 * @brief Hdcp Reset Auth Status.
 * @param[in] enPortIndex: Port index.
 * @return Status, 0-HV_SUCCESS, 1-HV_FAILURE..
 */
UCHAR8 Hv_Mw_Hdcp_GetValidHdcpPortIndex(LinkPortIndex enInputPortIndex);

/**
 * @brief Hdcp Set Active Port.
 * @param[in] enPortIndex: Port index.
 * @return Status, 0-HV_SUCCESS, 1-HV_FAILURE..
 */
HdcpCtrlData* Hv_Mw_Hdcp_GetHdcpData(UCHAR8 ucHdcpPortIndex);

/**
 * @brief  Dp Hdcp Mix Clear.
 * @param[in] enPortIndex: Port index.
 * @return Status, 0-HV_SUCCESS, 1-HV_FAILURE..
 */
VOID Hv_Mw_Hdcp_DpMixClr(UCHAR8 ucPortIndex);

/**
 * @brief  Set DP HDCP RX Data to occupy the HDCP Port.
 * @param[in] enPortIndex: Link Port index.
 * @return Status, 0-HV_SUCCESS, 1-HV_FAILURE..
 */
Status Hv_Mw_Hdcp_SetDpRxData(HdcpCtrlData* pstHdcpData, LinkPortIndex enInputPortIndex, UCHAR8 ucDpPortIndex);

/**
 * @brief  HDCP Interrupt Init, Register the handler for ISR of HDCP.
 * @param[in] None.
 * @return None.
 */
VOID Hv_Mw_Hdcp_InterruptInit();
VOID Hv_Mw_Hdcp_Retry(LinkPortIndex enInputPortIndex);

/**
 * @brief  Realse the HDCP Cm Status.
 * @param[in] enPortIndex: Link Port index.
 * @return Status, 0-HV_SUCCESS, 1-HV_FAILURE..
 */
Status Hv_Mw_Hdcp_RealseHdcpCmStatus(LinkPortIndex enInputPortIndex);

/**
 * @brief  Release the HDCP bingding Status.
 * @param[in] enPortIndex: Link Port index.
 * @return Status, 0-HV_SUCCESS, 1-HV_FAILURE..
 */
Status Hv_Mw_Hdcp_ReleaseHdcpBinding(LinkPortIndex enInputPortIndex);

/**
 * @brief  Get the HDCP Manager Data.
 * @param[in] VOID: None.
 * @return HDCP Manager Pointer for HDCP Data.
 */
HDCPManager* Hv_Mw_Hdcp_GetHdcpManager(VOID);

/**
 * @brief ReAutherOnsyn.
 * @param[in] Link Port Index.
 * @return Status, 0-HV_SUCCESS, 1-HV_FAILURE..
 */
Status Hv_Mw_Hdcp_HdmiReAtherOnSync(LinkPortIndex enInputPortIndex, BOOL bForced);

VOID Hv_Mw_Hdcp_DpResetLinkIntegrityFailure(UCHAR8 ucPortIndex);

UINT32 Hv_DecryptHdcpKey(HDCPKeyDataDBRegion *pstHdcpKey);

Status Hv_Mw_Hdcp_ReConfigRxDataPath(UCHAR8 ucHdcpPortIndex, LinkPortIndex enInputPortIndex);

Status Hv_Mw_Hdcp_DecryptKey(HDCPKeyDataDBRegion *pstHdcpKey);
Status Hv_Mw_Hdcp_DDCCIWriteHdcp1xKey(USHORT16 usKeyLength, const UCHAR8 *pucHdcpKey);
Status Hv_Mw_Hdcp_DDCCIWriteHdcp2xKey(USHORT16 usKeyLength, const UCHAR8 *pucHdcpKey);
Status Hv_Mw_Hdcp_DDCCIEraseHdcp1xKey();
Status Hv_Mw_Hdcp_DDCCIEraseHdcp2xKey();
Status Hv_Mw_Hdcp_DDCCIWriteHdcp1xKeyId(USHORT16 usKeyLength, const UCHAR8 *pucHdcpKey);
Status Hv_Mw_Hdcp_DDCCIWriteHdcp2xKeyId(USHORT16 usKeyLength, const UCHAR8 *pucHdcpKey);
Status Hv_Mw_Hdcp_DDCCIReadHdcp1xKeyId(USHORT16 usKeyLength, UCHAR8 *pucHdcpKey);
Status Hv_Mw_Hdcp_DDCCIReadHdcp2xKeyId(USHORT16 usKeyLength, UCHAR8 *pucHdcpKey);
Status Hv_Mw_Hdcp_DDCCIReadHdcpBksv(USHORT16 usKeyLength, UCHAR8 *pucData);
Status Hv_Mw_Hdcp_HdmiSetEessQstc(LinkPortIndex enInputPortIndex);
HdcpKeyCheckResult Hv_Mw_Hdcp_CheckHdcpKey(HdcpVersion bHdcpVer);
BOOL Hv_Mw_Hdcp_CheckKsvValid(UCHAR8 *pucData);

#endif
