/* SPDX-License-Identifier: LGPL-2.1-only OR BSD-3-Clause */
/******************************************************************************
 *
 * This file is provided under a dual license.  When you use or
 * distribute this software, you may choose to be licensed under
 * version 2.1 of the GNU Lesser General Public License
 * ("LGPLv2.1 License") or BSD License.
 *
 * LGPLv2.1 License
 *
 * Copyright(C) 2019 MediaTek Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of version 2.1 of the GNU Lesser General Public
 * License as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html for more
 * details.
 *
 * BSD LICENSE
 *
 * Copyright(C) 2019 MediaTek Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of the copyright holder nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *****************************************************************************/

/*-----------------------------------------------------------------------------
 * $RCSfile: x_ci.h,v $
 * $Revision: #1 $
 * $Date: 2015/07/28 $
 * $Author: dtvbm11 $
 *
 * Description:
 *         This header file contains Common Interface (CI) specific
 *         definitions, which are exported.
 *-----------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
/*! @addtogroup groupMW_CI
*  @{ 
*/
/*----------------------------------------------------------------------------*/

#ifndef _X_CI_H_
#define _X_CI_H_

/*-------------------------------------------------------------------------
                    include files
-------------------------------------------------------------------------*/
#include "u_ci.h"
#include "x_rm_dev_types.h"

/*-------------------------------------------------------------------------
                    macros, defines, typedefs, enums
 ------------------------------------------------------------------------*/

/*------------------------------------------------------------------*/
/*!@struct CI_CONFIG_T
 *  @brief CI config structure. 
 * typedef struct _CI_CONFIG_T
 *{
 *   UINT16  ui2_num_services;
 *   UINT16  ui2_num_comps;
 *   UINT16  ui2_num_src;
 *   DRV_TYPE_T* at_src_type; 
 *} CI_CONFIG_T;
 *  @endcode
  *  @li@c  ui2_num_services -Number of CA_SVDB node.
 *  @li@c  ui2_num_comps -Number of CA_ESDB node. 
 *  @li@c  ui2_num_src      -at_tuner_type array length
 *  @li@c  at_src_type      -tuner source array. 
 */
/*------------------------------------------------------------------*/
typedef struct _CI_CONFIG_T
{
    UINT16  ui2_num_services;
    UINT16  ui2_num_comps;
    UINT16  ui2_num_src;
    DRV_TYPE_T* at_src_type;
} CI_CONFIG_T;

/*------------------------------------------------------------------*/
/*! @enum CIPLUS_CRED_DESC_ALG_T
 *  @brief  specifies credential descrambler algorithm type
 *  @code
 *  typedef enum
 *{
 *   CIPLUS_CRED_DESC_ALG_NONE
 *   CIPLUS_CRED_DESC_ALG_AES_128_CBC
 *} CIPLUS_CRED_DESC_ALG_T;
 *  @endcode
 *  @li@c  CIPLUS_CRED_DESC_ALG_NONE            -  none algorigthm
 *  @li@c  CIPLUS_CRED_DESC_ALG_AES_128_CBC            -  algorithm is AES_128_CBC type
 */
/*------------------------------------------------------------------*/
typedef enum
{
    CIPLUS_CRED_DESC_ALG_NONE,
    CIPLUS_CRED_DESC_ALG_AES_128_CBC
}CIPLUS_CRED_DESC_ALG_T;

/*------------------------------------------------------------------*/
/*!@struct CI_PLUS_CRED_INFO_T
 *  @brief This structure defines ci plus credential infomation data.
 *typedef struct _CIPLUS_CONFIG_T
 *{
 *   BOOL b_fix_key;
 *   CIPLUS_CRED_DESC_ALG_T t_desc_alg; 
 *   union
 *   {
 *       struct
 *       {
 *            SIZE_T          z_key_len;    
 *           UINT8           aui1_key[16];
 *            SIZE_T          z_iv_len;    
 *           UINT8           aui1_iv[16];      
 *      }aes_128_cbc;
 *   }u_data;
 *    BOOL b_custom_code;       
 *   UINT8 ui1_max_len_code;   
 *  UINT8 ui1_len_code;      
 *  CHAR  *pc_custom_code;   
 *   UINT8 ui1_max_search_pattern_len;   
 *   CI_SEARCH_MODE_DATA_T t_search_mode_data;   
 *    CHAR  *pc_dst_path;    
 *    BOOL  b_rename_after_write;     
 *   UINT8 ui1_max_rename_prefix_len;  
 *   UINT8 ui1_rename_prefix_len;   
 *   CHAR  *pc_rename_prefix;       
 *    UINT8 ui1_max_serial_num_len;   
 *}CIPLUS_CONFIG_T;
 *  @endcode
 *  @li@c  b_fix_key      -contains the flag it is true if valid.
 *  @li@c  t_desc_alg      -algorithm used for encrypt the ciplus credentials.
 *  @li@c  z_key_len      -size of key in byte.
 *  @li@c  aui1_key      - pointer of key buffer
 *  @li@c  z_iv_len      -size of iv in byte 
 *  @li@c  aui1_iv      -pointer of iv buffer
 *  @li@c  b_custom_code      -valid flag of custom code setting.
 *  @li@c  ui1_max_len_code      -the maxium length of custom code
 *  @li@c  ui1_len_code      - length of custom code
 *  @li@c  pc_custom_code      -poniter of custom code 
 *  @li@c  ui1_max_search_pattern_len      -the maxium string length of search pattern 
 *  @li@c  t_search_mode_data      -search mode and pattern of files in external storage
 *  @li@c  b_preburn_cred_separated      - flag to identify to separted the store partition of preburn credentials
 *  @li@c  pc_pre_burn_dst_path      -destination file for pre-burn the ci plus data into flash
 *  @li@c  pc_dst_path      -destination file for writting ci plus data in flash
 *  @li@c  b_rename_after_write      -valid flag of rename file after written done
 *  @li@c  ui1_max_rename_prefix_len      -the maxium length of custom code 
 *  @li@c  ui1_rename_prefix_len      -length of rename prefix  
 *  @li@c  pc_rename_prefix      -pointer of string for rename prefix
 *  @li@c  ui1_max_serial_num_len      -the maxium length of serial number 
 */
/*------------------------------------------------------------------*/
typedef struct _CIPLUS_CONFIG_T
{
    BOOL b_fix_key;
    CIPLUS_CRED_DESC_ALG_T t_desc_alg; 
    union
    {
        struct
        {
            SIZE_T          z_key_len;    
            UINT8           aui1_key[16];
            SIZE_T          z_iv_len;    
            UINT8           aui1_iv[16];      
        }aes_128_cbc;
    }u_data;

    BOOL b_custom_code;       
    UINT8 ui1_max_len_code;   
    UINT8 ui1_len_code;      
    CHAR  *pc_custom_code;   

    UINT8 ui1_max_search_pattern_len;   
    CI_SEARCH_MODE_DATA_T t_search_mode_data;   

    BOOL  b_preburn_cred_separated;
    CHAR  *pc_preburn_dst_path;
    CHAR  *pc_dst_path;    
    
    BOOL  b_rename_after_write;     
    UINT8 ui1_max_rename_prefix_len;  
    UINT8 ui1_rename_prefix_len;   
    CHAR  *pc_rename_prefix;       

    UINT8 ui1_max_serial_num_len;   
    BOOL  b_product_key;
    
    CHAR  *pc_akh_path;
}CIPLUS_CONFIG_T;
typedef struct _CIPLUS_V13_CONFIG_T
{
    UINT8 service_type_loop_length;
    CI_SVC_TYPE_SUPPORT_T *service_type;
    UINT8 delivery_capability_loop_length;
    CI_DELIVERY_SYS_SUPPORT_T *delivery_capability;
    UINT8 application_capability_loop_length;
    CI_APP_TYPE_SUPPORT_T *application_capability;
}CIPLUS_V13_CONFIG_T;
/*-------------------------------------------------------------------------
                    Functions
 ------------------------------------------------------------------------*/
/*------------------------------------------------------------------*/
/*! @brief config ci engine this api should be called before x_ci_init().
 *  @param [in] ui2_num_services -Number of CA_SVDB node.
 *  @param [in] ui2_num_comps -Number of CA_ESDB node. 
 *  @param [in] ui2_num_src -at_tuner_type array length
 *  @param [in] at_tuner_type -tuner source array. 
 *  @note
 *  @see c_ci_unreg_nfy
 *  @return
 *  @retval      CIR_OK -the routine is successful
 *  @retval      CIR_NOT_REGISTERED -ci engine has not registered 
 *  @retval      CIR_NOT_INIT -ci engine has not initialized 
 *  @retval      CIR_NOT_ENOUGH_SPACE -allocated memory failed
 */
/*------------------------------------------------------------------*/
extern VOID x_ci_config(UINT16  ui2_num_services, 
                   UINT16  ui2_num_comps,
                   UINT16  ui2_num_src,
                   DRV_TYPE_T *at_tuner_type);

/*------------------------------------------------------------------*/
/*! @brief initialize ci engine, called when system startup
 *  @param [in] ui2_sw_version -software version
 *  @note
 *  @see x_ci_config()
 *  @return
 *  @retval      CIR_OK -the routine is successful
 *  @retval      CIR_ALREADY_INIT -ci engine has already initialized 
 *  @retval      CIR_INIT_FAILED -ci engine initialized failed
 */
/*------------------------------------------------------------------*/
extern INT32 x_ci_init(UINT16 ui2_sw_version);
/*------------------------------------------------------------------*/
/*! @brief config ci plus engine this api should be called before x_ci_init().
 *  @param [in] t_ciplu_cfg -configure data
 *  @note
 *  @see CIPLUS_CONFIG_T
 *  @return
 *  @retval      CIR_OK -the routine is successful
 *  @retval      CIR_NOT_REGISTERED -ci engine has not registered 
 *  @retval      CIR_NOT_INIT -ci engine has not initialized 
 *  @retval      CIR_NOT_ENOUGH_SPACE -allocated memory failed
 */
/*------------------------------------------------------------------*/
extern VOID x_ciplus_config(CIPLUS_CONFIG_T *t_ciplu_cfg);
/*------------------------------------------------------------------*/
/*! @brief config ci plus engine this api should be called before x_ci_init().
 *  @param [in] t_ciplu_cfg -configure data
 *  @note
 *  @see CIPLUS_V13_CONFIG_T
 *  @return
 *  @retval      CIR_OK -the routine is successful
 *  @retval      CIR_NOT_REGISTERED -ci engine has not registered 
 *  @retval      CIR_NOT_INIT -ci engine has not initialized 
 *  @retval      CIR_NOT_ENOUGH_SPACE -allocated memory failed
 */
/*------------------------------------------------------------------*/
extern VOID x_ciplus_v13_config(CIPLUS_V13_CONFIG_T *t_ciplu_cfg);
/*------------------------------------------------------------------*/
/*! @brief register notification callback function
 *  @param [in] pv_nfy_tag -private tag for caller who will be set in x_ci_nfy_fct() callback when notify caller
 *  @param [in] pv_nfy -callback function pointer,CI engine will notify event through this function.
 *  @param [out] ph_ci -handle for this register action who will be used in x_ci_nfy_fct() and x_ci_unreg_nfy()
 *  @note
 *  @see c_ci_unreg_nfy
 *  @return
 *  @retval      CIR_OK -the routine is successful
 *  @retval      CIR_NOT_REGISTERED -ci engine has not registered 
 *  @retval      CIR_NOT_INIT -ci engine has not initialized 
 *  @retval      CIR_NOT_ENOUGH_SPACE -allocated memory failed
 */
/*------------------------------------------------------------------*/
extern INT32 x_ci_reg_nfy(
    HANDLE_T*           ph_ci,
    VOID*               pv_nfy_tag,
    UINT32              ui4_nfy_category_tag,
    x_ci_nfy_fct        pv_nfy);

/*------------------------------------------------------------------*/
/*! @brief unregister notification callback function
 *  @param [in] h_ci -handle for unregister which is set in x_ci_reg_nfy()
 *  @param [out] NONE
 *  @note
 *  @see x_ci_reg_nfy
 *  @return
 *  @retval      CIR_OK -the routine is successful
 *  @retval      CIR_NOT_REGISTERED -no related callback function registered 
 *  @retval      CIR_NOT_INIT -ci engine has not initialized 
 */
/*------------------------------------------------------------------*/

extern INT32 x_ci_unreg_nfy(
    HANDLE_T            h_ci);

/*------------------------------------------------------------------*/
/*! @brief register query callback function
 *  @param [in] pv_tag -private tag for caller who will be set in x_ci_query_info_fct() callback when query data
 *  @param [in] pf_query_info_fct -callback function pointer,CI engine will query data through this function.
 *  @param [out] ph_ci -handle for this register action who will be used in x_ci_query_info_fct() 
 *  @note
 *  @see c_ci_unreg_nfy
 *  @return
 *  @retval      CIR_OK -the routine is successful
 *  @retval      CIR_NOT_REGISTERED -ci engine has not registered 
 *  @retval      CIR_NOT_INIT -ci engine has not initialized 
 *  @retval      CIR_NOT_ENOUGH_SPACE -allocated memory failed
 */
/*------------------------------------------------------------------*/
extern INT32 x_ci_reg_query_nfy(
    HANDLE_T*           ph_ci,
    VOID*               pv_tag,
    UINT32              ui4_nfy_category_tag,
    x_ci_query_info_fct pf_query_info_fct);


/*------------------------------------------------------------------*/
/*! @brief query CI  info
 *  @param [in] e_get_type -query type
 *  @param [in,out] pv_data -queried data, concrete type depends on e_get_type
 *  @param [in,out] pz_data_len -data's length
 *  @note
 *  @see
 *  @return
 *  @retval      CIR_OK -the routine is successful
 *  @retval      CIR_INV_GET_INFO -pv_get_info value is invalid
 *  @retval      CIR_INV_GET_DATA -pv_data value is invalid
 *  @retval      CIR_NOT_REGISTERED -no related callback function registered 
 *  @retval      CIR_NOT_INIT -ci engine has not initialized 
 *  @retval      CIR_NOT_ENOUGH_SPACE -allocated memory failed
 */
/*------------------------------------------------------------------*/

extern INT32 x_ci_get(
    CI_GET_TYPE_T       e_get_type,
    VOID*               pv_get_info,
    VOID*               pv_data,
    SIZE_T*             pz_data_len);
/*------------------------------------------------------------------*/
/*! @brief set CI  info
 *  @param [in] e_set_type -set type
 *  @param [in] pv_set_info -set info data
 *  @param [in] pv_data -set data
 *  @note
 *  @see
 *  @return
 *  @retval      CIR_OK -the routine is successful
 *  @retval      CIR_INV_SET_TYPE -e_set_type value is invalid
 *  @retval      CIR_INV_SET_INFO -pv_set_info value is invalid
 *  @retval      CIR_INV_SET_DATA -pv_data value is invalid
 *  @retval      CIR_NOT_REGISTERED -no related callback function registered 
 *  @retval      CIR_NOT_INIT -ci engine has not initialized 
 *  @retval      CIR_ALREADY_SET_ENTER_MENU -menu has been already entered
 *  @retval      CIR_FAILED -the routine is failed
 */
/*------------------------------------------------------------------*/

extern INT32 x_ci_set(
    CI_SET_TYPE_T       e_set_type,
    VOID*               pv_set_info,
    VOID*               pv_data);

/*------------------------------------------------------------------*/
/*! @brief set ts path route 
 *  @param [in] b_enable_ts - True means ts data pass through CAM, False means ts data bypass CAM
 *  @note
 *  @see
 *  @return
 *  @retval      CIR_OK -the routine is successful
 *  @retval      CIR_FAILED -the routine is failed
 */
/*------------------------------------------------------------------*/
extern INT32 x_ci_set_ts_route_path(BOOL b_enable_ts);

/*------------------------------------------------------------------*/
/*! @brief get CAM if is insert on the Host
 *  @param NONE
 *  @note
 *  @see
 *  @return CAM insert state
 *  @retval      True - means CAM is inserted
 *  @retval      False - means CAM is not inserted
 */
/*------------------------------------------------------------------*/
extern BOOL x_ci_get_cam_insert(VOID);

/*API's between MHEG5 module and CI module*/

/*------------------------------------------------------------------*/
/*! @brief register mheg5 notification callback function
 *  @param [in] pv_nfy_tag -private tag for caller who will be set in x_ci_mheg5_nfy_fct() callback when notify caller
 *  @param [in] pv_nfy -callback function pointer,CI engine will notify event through this function.
 *  @param [out] ph_ci -handle for this register action who will be used in x_ci_mheg5_nfy_fct()
 *  @note
 *  @see x_ci_mheg5_nfy_fct
 *  @return
 *  @retval      CIR_OK -the routine is successful
 *  @retval      CIR_NOT_REGISTERED -ci engine has not registered 
 *  @retval      CIR_NOT_INIT -ci engine has not initialized 
 *  @retval      CIR_NOT_ENOUGH_SPACE -allocated memory failed
 */
/*------------------------------------------------------------------*/
extern INT32 x_ci_mheg5_reg_nfy(
    HANDLE_T*           ph_ci,
    VOID*               pv_nfy_tag,
    x_ci_mheg5_nfy_fct  pv_nfy);

/*------------------------------------------------------------------*/
/*! @brief set mheg5 info
 *  @param [in] e_set_type -set type
 *  @param [in] pv_data -set data
 *  @note
 *  @see CI_MHEG5_SET_TYPE
 *  @return
 *  @retval      CIR_OK -the routine is successful
 *  @retval      CIR_INV_SET_TYPE -e_set_type value is invalid
 *  @retval      CIR_INV_SET_DATA -pv_data value is invalid
 *  @retval      CIR_NOT_REGISTERED -no related callback function registered 
 *  @retval      CIR_NOT_INIT -ci engine has not initialized 
 *  @retval      CIR_FAILED -the routine is failed
 */
/*------------------------------------------------------------------*/
extern INT32 x_ci_mheg5_set(
    CI_MHEG5_SET_TYPE   e_set_type,
    VOID*               pv_data);

/*------------------------------------------------------------------*/
/*! @brief This API return the max slot number
 *  @param [in]
 *  @param [out] 
 *  @note
 *  @see
 *  @return
 *  @retval max slot number
 */
 /*------------------------------------------------------------------*/
extern UINT8 x_ci_fac_get_max_slot_num(VOID);

/*------------------------------------------------------------------*/
/*! @brief This API return the cam insert status
 *  @param [in] slot number, start from 0
 *  @param [out] pointer to keep the CAM appear status
 *  @note
 *  @see
 *  @return 
 *  @retval    CIR_OK-                  The routine was successful.
 *  @retval    CIR_FAILED-              Tthe routine is failed.
 */
 /*------------------------------------------------------------------*/
extern INT32 x_ci_fac_get_cam_appear_status(UINT8 ui1_slot, CI_APPEAR_COND_T *pt_status);

/*------------------------------------------------------------------*/
/*! @brief This API performs set TS path goes through CAM.
 *  @param [in] TRUE  - Set TS through CI module. FALSE - Set TS bypass CI module. 
 *  @note
 *  @see
 *  @return 
 *  @retval    CIR_OK-                  The routine was successful.
 *  @retval    CIR_FAILED-              Tthe routine is failed.
 */
 /*------------------------------------------------------------------*/
extern INT32 x_ci_set_force_through_cam(BOOL b_through_cam);

/*------------------------------------------------------------------*/
/*! @brief This API performs getting TS path pass or pass though CAM
 *  @param [in] 
 *  @note
 *  @see
 *  @return 
 *  @retval    TRUE  - TS through CI module. 
 *  @retval    FALSE - S bypass CI module. 
 */
 /*------------------------------------------------------------------*/
extern BOOL x_ci_get_enablets_status(VOID);

typedef INT32 (* ci_parse_tbl_fct)(VOID*          pv_tag,
                                     VOID*          pv_src_tag,
                                     SIZE_T         z_data_len,
                                     UINT8          ui1_secm_num,
                                     UINT8          ui1_firse_num,
                                     UINT8          ui1_last_num);

extern INT32 x_ci_load_and_parse_pmt(VOID* pv_tag,ci_parse_tbl_fct pf_parse);
extern INT32 x_ci_get_pmt_raw_sect(UINT8* pui1_pmt_data,SIZE_T* pz_len);

extern INT32 x_ci_update_tuner_info(CHAR* ps_tuner_name,UINT16 ui2_tsl_id,UINT16 ui2_svl_id);

/*------------------------------------------------------------------*/
/*! @brief This API performs getting CI+ key store status
 *  @param [in] 
 *  @note
 *  @see
 *  @return 
 *  @retval    TRUE  - ciplus key is installed.
 *  @retval    FALSE - ciplus key store is empty.
 */
 /*------------------------------------------------------------------*/
extern BOOL x_ci_get_ciplus_key_store_status(VOID);
#endif /* _X_CI_H_ */ 

/*----------------------------------------------------------------------------*/
/*! @} */   /* end of  groupMW_CI*/
/*----------------------------------------------------------------------------*/
