/**
* Copyright(c) 2011 Sunmedia Technologies - All Rights Reserved.
*
* @file al_psi_monitor.h
*
* @brief this file defines psi monitor interface for app layer.
*
* The file supports the psi monitor functions by used for app layer.
* The psi monitor check all psi and si table changed,
* if table change parse and update information to database and notify application dispose.
*
*/

#ifndef __AL_PSI_MONITOR_H__
#define __AL_PSI_MONITOR_H__

#include "al_basictypes.h"
#include "dvb_dr.h"
#include "al_database.h"

#ifdef __cplusplus
	extern "C"{
#endif

/**
* @brief Psi monitor dispose max other tp service namber.
*/
#define PSIMON_MAX_OTHERTP_SRV			100
#define PSIMON_MAX_EWSDETAIL_LEN        256
/**
* @brief Psi monitor special spec define.
*/
typedef enum
{
	AL_PSIMON_SPECIAL_SPEC_NONE = DVB_SPECIAL_SPEC_NONE, /**< None spec */
	AL_PSIMON_SPECIAL_SPEC_DTG = DVB_SPECIAL_SPEC_DTG, /**< DBOOK spec for UK */
	AL_PSIMON_SPECIAL_SPEC_ZBOOK = DVB_SPECIAL_SPEC_ZBOOK, /**< ZBOOK spec for ITALY */
	AL_PSIMON_SPECIAL_SPEC_NORDIG = DVB_SPECIAL_SPEC_NORDIG, /**< NORDIG spec for FINLAND, SWEDEN, DENMARK, NORWAY, GERMANY */
	AL_PSIMON_SPECIAL_SPEC_EBOOK = DVB_SPECIAL_SPEC_EBOOK, /**< EBOOK spec */
	AL_PSIMON_SPECIAL_SPEC_BASEON_PDSD = DVB_SPECIAL_SPEC_BASEON_PDSD,
	AL_PSIMON_SPECIAL_SPEC_THAI = DVB_SPECIAL_SPEC_THAI,
#ifdef DVB_S
    AL_PSIMON_SPECIAL_SPEC_DVBS_TEST = DVB_SPECAIL_SPEC_DVBS_TEST,
#endif
#ifdef CONFIG_SUPPORT_FAST_SCANNING
    AL_PSIMON_SPECIAL_SPEC_M7_FASTSCAN = DVB_SPECIAL_SPEC_M7_FASTSCAN,
#endif
	AL_PSIMON_SPECIAL_SPEC_DEMO_DEFAULT = DVB_SPECIAL_SPEC_DEMO_DEFAULT,
} AL_PSIMon_SpecialSpec_t;

/**
* @brief Define psi dynamic update options.
*/
typedef enum
{
	AL_PSIMONITOR_CURTP_SRVADD = 1<<0, /**< Check SDT and NIT in addition */
	AL_PSIMONITOR_CURTP_SRVADD2 = 1<<1, /**< Check PAT in addition */
	AL_PSIMONITOR_CURTP_SRV_ATR = 1<<2, /**< Service name & attribute update check */
	AL_PSIMONITOR_CURTP_SRV_REMOVE = 1<<3, /**< When service info was gone , the service will be removed */
	AL_PSIMONITOR_CURTP_SRV_MOVE = 1<<4, /**< Service move descriptor, move a service from one TS to another */
	AL_PSIMONITOR_CURTP_SRV_REPLACE = 1<<5, /**< Service replacement check */
	AL_PSIMONITOR_LCN_DYNAMIC_UPDATE = 1<<6, /**< To support dynamic lcn update */
	AL_PSIMONITOR_OTHTP_SR_ADD = 1<<7, /**< Check other tp's service if any new tp found, its services add to database automatically */
	AL_PSIMONITOR_REPLACED_TO_ORIGNAL = 1<<8, /**< Service from replaced state to orignal state */
	AL_PSIMONITOR_OTHTP_FOND = 1<<9, /**< Check other tp frequency is change in nit, start to scan automatically */
	AL_PSIMONITOR_USER_TOTOFFSET = 1<<10, /**< if has TOT and country matched, forced use tot time offset */
	AL_PSIMONITOR_OTHTP_SR_UPDATE = 1<< 11, /**< Other tp sdt to update service info */
#ifdef SUPPORT_NETWORK_UPDATE_RESCAN
	AL_PSIMONITOR_CURNWK_TP_RESCAN = 1<< 12, /**< Rescan to add/remove other tp */
#endif
	AL_PSIMONITOR_KDG_LCN_DYNAMIC_UPDATE = 1<<13, /**< To support dynamic lcn update for Operator KDG */
	AL_PSIMONITOR_CURTP_SRVADDCHECKPMT = 1<<14, /**< Check PMT in addition */
	AL_PSIMONITOR_FREQ_UPDATE = 1<< 15,
} AL_PsiMon_DynamicUpdate_Type_t;


/**
* @brief Define sipsi state.
*/
typedef enum
{
	AL_PSIMONITOR_STATE_NOT_RUNNING_FLAG = (1<<1), /**< Current program is not running, sdt running status is 0x01 */
	AL_PSIMONITOR_STATE_NOT_RUNNING_REPLACEMENT_EXIST = (1<<2), /**< Not running replacement exist, lingkage type is 0x05 */
	AL_PSIMONITOR_STATE_SCRAMBLED_REPLACEMENT_EXIST = (1<<3), /**< Scramble replacement exist, lingkage type is 0x03 */
	AL_PSIMONITOR_STATE_SIMULCAST_REPLACEMENT_EXIST = (1<<4), /**< Simulcast replacement exist, lingkage type is 0x82 , for NORDIG spec */
	AL_PSIMONITOR_STATE_NOT_RUNNING_REPLACED = (1<<5), /**< Not running replaced,  has disposed not running replacement */
	AL_PSIMONITOR_STATE_SCRAMBLED_REPLACED = (1<<6),  /**< Scramble replaced,  has disposed scramble replacement */
	AL_PSIMONITOR_STATE_SIMULCAST_REPLACED = (1<<7), /**< Simulcast replaced, has dispose simulcase scramble replacement */
#ifdef EPG_REPLACE
	AL_PSIMONITOR_STATE_EPG_REPLACEMENT_EXIST = (1<<8), /**< EPG replacement exist, lingkage type is 0x04 , for boxer spec */
	AL_PSIMONITOR_STATE_EPG_REPLACED = (1<<9), /**< EPG replaced, has disposed EPG replacement */
#endif
	AL_PSIMONITOR_STATE_MAX,
} AL_PsiMon_State_Type_t;


/**
* @brief Psi monitor simple service, used to service dynmc add and remove.
*/
typedef struct _PSIMon_SimpleSrv
{
	al_uint16 usOrgNetId; /**< orignal net work id */
	al_uint16 usNetWorkId; /** network id form NIT <*/ /*zhongbaoxing added fo NorDig test*/
	al_uint16 usTsId; /**< transport stream id */
	al_uint16 usPat_TsId;
	al_uint16 usServiceId; /**< service id */
	al_uint16 usProgNum; /**< program number */
	al_uint16	usPMTPid; /**< pmt pid */
	AL_DB_ERecordType_t ucServiceType; /**< service type */
	al_uint8 u8SDTSrvType;
	al_int32 uiFreq; /**< frequecy */
	al_uint8 *pucname; /**< program name */
	DBServAttrib_t stProgAttrib;
	struct _PSIMon_SimpleSrv *pstNext;
} AL_PSIMon_SimpleSrv_t;

/**
* @brief Psi monitor audio comp data, used to multi audio dispose.
*/
typedef struct _PsiMon_AudioComp
{
	al_uint8 u8StreamType; /**< stream_type */
	al_uint16 u16ElementaryPid; /**< elementary_pid */
	al_uint16 u16DescLen; /**< total descriptor length */
	al_uint8 	*pu8Desc; /**< pointer to descriptor */
	struct _PsiMon_AudioComp *pstNext;
} AL_PsiMon_AudioComp_t;

/**
* @brief Psi monitor new service position for move descriptor.
*/
typedef struct _PsiMon_NewSrvPosition
{
	al_uint16 usOldServiceId; /**< Old service id */
	al_uint16 usOrgNetId; /**< Orignal network id */
	al_uint16 usTsId; /**< Transport id */
	al_uint16 usServiceId; /**< New service id */
} AL_PsiMon_NewSrvPosition_t;
#ifdef CONFIG_SUPPORT_INDONESIA_EWS

#include "mid_siutil_dvb.h"

typedef struct _PsiMon_EwsTrdwInfo
{
	al_uint16 usDisaster;
	al_uint16 usLocationType;
	al_uint8  u8PackageId;
	al_uint8  u8NumLocations;
	SI_EWS_TRDW_LOCATION* locations;
} AL_PsiMon_EwsTrdwInfo_t;

typedef struct _PsiMon_EwsTcdwInfo
{
	al_uint8  u8PackageId;
	al_uint8  u8Authority;
	al_uint16 usDisaster;
	SI_STRING_DESC* disaster_name;
	SI_STRING_DESC* disaster_position;
	SI_STRING_DESC* disaster_date;
	SI_STRING_DESC* disaster_characteristic;
} AL_PsiMon_EwsTcdwInfo_t;

typedef struct _PsiMon_EwsTmdwInfo
{
	al_uint16 usLocationType;
	al_uint8  u8PackageId;
	al_uint8  u8NumMessages;
	SI_STRING_DESC** messages;
} AL_PsiMon_EwsTmdwInfo_t;

typedef struct _PsiMon_EwsList
{
	al_uint8  u8NumTrdwEntries;
	al_uint32 u32TrdwCrc32;
	AL_PsiMon_EwsTrdwInfo_t *trdwEntries;

	al_uint8  u8NumTcdwEntries;
	al_uint32 u32TcdwCrc32;
	AL_PsiMon_EwsTcdwInfo_t *tcdwEntries;

	al_uint8  u8NumTmdwEntries;
	al_uint32 u32TmdwCrc32;
	AL_PsiMon_EwsTmdwInfo_t *tmdwEntries;
} AL_PsiMon_EwsList_t;

typedef struct _PsiMon_EwsDetail
{
	// from TRDW
	al_uint16 usDisaster;
	al_uint16 usLocationType;
	al_uint8  u8PackageId;
	al_uint8  location_name[PSIMON_MAX_EWSDETAIL_LEN];
	// from TCDW
	al_uint8  u8Authority;
	al_uint8  disaster_name[PSIMON_MAX_EWSDETAIL_LEN];
	al_uint8  disaster_position[PSIMON_MAX_EWSDETAIL_LEN];
	al_uint8  disaster_date[PSIMON_MAX_EWSDETAIL_LEN];
	al_uint8  disaster_characteristic[PSIMON_MAX_EWSDETAIL_LEN];
	// from TMDW
	al_uint8  *message;  // need to be freed explicitly by caller
} AL_PsiMon_EwsDetail_t;

AL_Return_t AL_PSI_Monitor_GetEwsDetail(al_uint32 u16AreaCode, AL_PsiMon_EwsDetail_t *ewsDetail);

#endif

/**
* @brief Call back function prototype for application to register.
*/
typedef	al_void (* AL_pfPsiMonCheckSrvType)(al_uint8 SdtSrvType, al_uint8 SrvType, al_uint8 VideoCount, al_uint8 AudioCount, AL_DB_ERecordType_t *RetSrvType);

typedef al_void (* AL_pfPsiMonCheckNotVisible)(al_uint8 SdtSrvType, al_uint8 bTempSrv, al_uint8 *bNotVisible, al_uint8 *bNotNeedSave);

/**
* @brief psi monitor start function.
*
* Active psi monitor task, start to monitor psi table and si table change
*
* @param hCurrProg playback play program handle.
*
* @param ClearReplaceData the flag of clearing replace data.
*
* @return AL_SUCCESS start  is successful, AL_FAILURE otherwise.
*/
AL_Return_t AL_PSI_Monitor_Start(AL_RecHandle_t hCurrProg, al_bool ClearReplaceData);

/**
* @brief psi monitor stop function.
*
* Stop psi monitor task, stop to monitor psi table and si table
*
* @param bExit[input] used to mark hang up psi monitor task or exit psi monitor.
*
* @return AL_SUCCESS stop is successful, AL_FAILURE otherwise.
*/
AL_Return_t AL_PSI_Monitor_Stop(al_bool bExit, al_bool ClearReplaceData);

/**
* @brief get psi monitor running state function.
*
* Get dvb monitor current state.
*
* @param pbPsiMonState[output] psi monitor running state value.
*
* @return AL_SUCCESS get state is successful, AL_FAILURE otherwise.
*/
AL_Return_t AL_PSI_Monitor_GetState(al_bool *pbPsiMonState);

/**
* @brief set psi monitor special spec
*
* Because different contry have different spec, example UK(DBook), this api to set special spec.
*
* @param eSpecConf[input] spec config
*
* @param eDynamicUpdate[input] psi monitor support dynamic update type
*
* @param pfPsiMonCheckSrvType[input] usded to check service type(TV/RADIO/DATA)
*
* @param pfPsiMonCheckNotVisible[input] usded to check service not visible
*
* @return AL_SUCCESS setup spec config is successful, AL_FAILURE otherwise.
*/
AL_Return_t AL_PSI_Monitor_SetupConf(AL_PSIMon_SpecialSpec_t eSpecConf,
	AL_PsiMon_DynamicUpdate_Type_t eDynamicUpdate, AL_pfPsiMonCheckSrvType pfPsiMonCheckSrvType, AL_pfPsiMonCheckNotVisible pfPsiMonCheckNotVisible);

void AL_PSI_Monitor_NotAddService(void);

/**
* @brief Get other tp service list from nit service list.
*
* Nit include other tp information, this function used to get other tp service list.
*
* @param psrv[output] other tp service list.
*
* @param pName service name
*
* @param pu16SrvNum[output] service total count.
*
* @return AL_SUCCESS get other tp services is successful, AL_FAILURE otherwise.
*/
AL_Return_t AL_PSI_Monitor_GetOtherTpServList(AL_PSIMon_SimpleSrv_t *pSrv, al_uint8 *pName, al_uint16 *pu16SrvNum);

#ifdef SUPPORT_NETWORK_UPDATE_RESCAN
AL_Return_t AI_PSI_Monitor_UpdateCurrTpTSIDList(al_void);

AL_Return_t AI_PSI_Monitor_GetVariedTpListFreq(al_uint32 *pu32TpListFreq);
#endif

/**
* @brief Get current program audio component data.
*
* psi monitor received audio stream not do parse, store to cash buffer, provide to app get.
*
* @param pAudio[output] audio component data.
*
* @param pu16AudioNum[output] audio total count.
*
* @param pu16MinAudioPid[output] min audio pid.
*
* @param pu8VideoPidCount[output] video pid count.
*
* @return AL_SUCCESS get current program audio is successful, AL_FAILURE otherwise.
*/
AL_Return_t AL_PSI_Monitor_GetCurrProgAudio(AL_PsiMon_AudioComp_t *pAudio,al_uint16 *pu16AudioNum,
	al_uint16 *pu16MinAudioPid, al_uint8 *pu8VideoPidCount);

/**
* @brief Get new srv position.
*
* For dispose service move descriptor, it is include new service information.
*
* @param pSrvPosition[output] new service information, service id/ts id/org net id.
*
* @return AL_SUCCESS get new service position is successful, AL_FAILURE otherwise.
*/
AL_Return_t AL_PSI_Monitor_GetNewSrvPosition(AL_PsiMon_NewSrvPosition_t *pSrvPosition);

/**
* @brief psi monitor get FTA data.
*
* @ param pu8Data[output] the FTA data.
*
* @return AL_SUCCESS get dtg cmg data is successful, AL_FAILURE otherwise.
*/
AL_Return_t AL_PSI_Monitor_GetFTAData(al_uint8 *pu8Data);

/**
* @brief psi monitor get CA data.
*
* @ param pu16Data[output] the CA data.
*
* @return AL_SUCCESS get CA data is successful, AL_FAILURE otherwise.
*/
AL_Return_t AL_PSI_Monitor_GetCAData(al_uint16 *pu16Data);

/**
* @brief Check psi monitor sipsi state.
*
* This function used to check psi monitor sipsi info state,( NOT_RUNNING_REPLACEMENT_EXIST,
* NOT_RUNNING_FLAG, SCRAMBLED_REPLACEMENT_EXIST, NOT_RUNNING_REPLACED, SCRAMBLED_REPLACED).
*
* @param u32State[input] sipsi state.
*
* @param pParam[output] sipsi state's parameter, program handle for replacement.
*
* @return al_ture if state exist, al_false if state not exist.
*/
al_bool AL_PSI_Monitor_CheckState(al_uint32 u32State, AL_RecHandle_t *pParam);


#ifdef __cplusplus
}
#endif
#endif
