/*! \addtogroup SIUTIL * @{ */ /******************************************************************************/ /** * \file mid_siutil.h * * \brief header for all SI * * \note Copyright (C) 2006 SunMedia Co, chengdu * Author anlzhao@sunmedia.com.cn * * \author * * The source code in this file is written by anlzhao referring to * ETSI EN 300 468 and owned by SunMedia Coporation. The header defines all * the macro and common struct. You should include it in all file. * * BUGS: * ******************************************************************************/ #ifndef _MID_SIUTIL_H_20080327 #define _MID_SIUTIL_H_20080327 #include #include #include #include "mid_common.h" extern unsigned int sisdbgconf1; extern unsigned int sisdbgconf2; #ifndef CONFIG_SUPPORT_DEBUG_MESSAGE #define SI_DEBUG(level, fmt, args...) #define SI_DEBUG2(level, fmt, args...) #else #define SIDEBUG #ifdef SIDEBUG #define SI_DEBUG(level, fmt, args...) do {if (sisdbgconf1 & DBGCFG_PSI) fprintf(stderr, "[SIPSI] " fmt, ## args);}while(0) #define SI_DEBUG2(level, fmt, args...) do {if (sisdbgconf2 & DBGCFG_PSI) fprintf(stderr, "[SIPSI] " fmt, ## args);}while(0) #else #define SI_DEBUG(level, fmt, args...) #define SI_DEBUG2(level, fmt, args...) #endif #endif #define SAFR_FREE_FUNC(func_free, p) {if(p){ func_free(p); p = NULL;}} /* Max section size */ #define MAX_SECTION_SIZE_D4 4096 /**<\brief default section max size 12bits = 4096bytes */ /* Timeout */ #undef DEFAULT_TIMEOUT #define DEFAULT_TIMEOUT 500 typedef INT16 CHAN_INDEX; #define SERVICE_NAME_DEFAULT "NONAME" #define CARRIER_NAME_DEFAULT "TPS" #define INVALID_INDEX (-1) #define MID_SIUTIL_CHANNELS_PER_UNIT 16 #define MID_SIUTIL_TOTAL_CHANNELS MID_SIUTIL_CHANNELS_PER_UNIT*DEMUX_TOTAL_UNITS #define CRC_LEN 4 #define SAFE_DELETE_QUEUE(p) {if(p){GL_QueueDelete(p); p = NULL;}} #define HILO(x) (x##_hi << 8 | x##_lo) #define MID_SIUTIL_IS_CHANIDX_VALID(n) (n >= 0 && n < MID_SIUTIL_TOTAL_CHANNELS) #define INVALID_HANDLE (0xffff) /** * \brief PSI crc check option */ typedef enum { CRC_CHECK_AUTO = 0, ///< only calculate CRC when section_syntax_indicator CRC_CHECK_NONE, ///< do not check CRC CRC_CHECK_FORCE, ///< do check CRC #ifdef DRV_DEMUX_SUPPORT_SUB_CHANNEL // for demux sub1 PVR channel CRC_CHECK_AUTO_SUB1 = 100, CRC_CHECK_NONE_SUB1, CRC_CHECK_FORCE_SUB1, // for demux sub2 PVR channel CRC_CHECK_AUTO_SUB2 = 200, CRC_CHECK_NONE_SUB2, CRC_CHECK_FORCE_SUB2, #endif // #ifdef DRV_DEMUX_SUPPORT_SUB_CHANNEL }MID_SIUTIL_CRC_CHECK; // ================ Common SI related ======================= // /** * \brief SI structure */ typedef struct _mid_siutil_si_table_header_t { UINT8 table_id :8; /**<\brief table_id */ UINT8 section_length_hi :4; /**<\brief section_length high bit */ UINT8 :3; UINT8 section_syntax_indicator :1; /**<\brief section_syntax_indicator */ UINT8 section_length_lo :8; /**<\brief section_length low bit */ UINT8 id_hi :8; /**<\brief extend id high bit */ UINT8 id_lo :8; /**<\brief extend id low bit */ UINT8 current_next_indicator :1; /**<\brief current_next_indicator */ UINT8 version_number :5; /**<\brief version_number */ UINT8 :2; UINT8 section_number :8; /**<\brief section_number */ UINT8 last_section_number :8; /**<\brief last_section_number */ }MID_SiutilSiTableHeader_t, *LP_MID_SiutilSiTableHeader_t; /** * \brief SI descriptor structure */ typedef struct _mid_siutil_si_descriptor { UINT8 tag; ///<\brief descriptor tag UINT8 len; ///<\brief descriptor length UINT8 content[1]; ///<\brief pointer to descriptor content }MID_SiutilSiDescr_t, *LP_MID_SiutilSiDescr_t; #define MAX_BUF_LEN 256 /** * \brief SI singlge section storing struct */ typedef struct _mid_si_section_t { UINT16 iSecNo; ///<\brief section_number UINT16 iSecLen; ///<\brief section length UINT8 *pSec; ///<\brief pointer to section content }MID_SiutilSiSection_t, *LP_MID_SiutilSiSection_t; typedef struct _mid_si_section_cb_param_t { volatile UINT8 bSignaled; /* for all section collected */ UINT8 iTotalSecNum; /* total sections */ UINT8 iCollectSecNum; /* currently collected sections */ UINT8 version; MID_SiutilSiSection_t stSections[MAX_BUF_LEN]; }MID_SiutilSectionCbParam_t, *LPMID_SiutilSectionCbParam_t; #define PRIVATE_LEN 9 typedef struct { UINT8 section_num; UINT16 version_num; UINT16 tbl_id_ext; UINT16 len; UINT8 *pPayload; }MID_SiutilPrivateSection_t; /** * \brief channels structure */ typedef struct _mid_siutil_channels_t { UINT16 pid; ///>\brief PID INT16 table_id_ext; ///>\brief extend_id INT8 table_id; ///>\brief table_id bool bIsMultiSection; ///>\brief Is multi section or not int hChanHdl; UINT16 filter_id; GL_Queue_t hChanEQHdl; ///>\brief event queue handle for the specific opened demux channel MID_SiutilSectionCbParam_t sections; }MID_SiutilChannels_t, *LP_MID_SiutilChannels_t; /* * siutil.c */ /************************************************************************************* * Definition of SIUTIL module interfaces *************************************************************************************/ /** \addtogroup Initialize * \brief initialize and uninitialize * @{ */ /************************************************************************************/ /** * \fn INT32 MID_SIUTIL_Init(void) * * \param none. * * \return 1 for successful, 0 for failed. * * \note Description : * Initialize SIUTIL engine for collect SI/PSI information. * ************************************************************************************/ INT32 MID_SIUTIL_Init(void); /************************************************************************************/ /** * \fn INT32 MID_SIUTIL_Uninit(void) * * \param none. * * \return none. * * \note Description : * Uninitialize SIUTIL engine. * ************************************************************************************/ void MID_SIUTIL_Uninit(void); /** @} end of addtogroup Initialize */ /** \addtogroup Section_operation Section Operation * \brief sections operations * * collect all sections corresponding to the same demux event queue * return the received section corresponding channel index maintained by siutil module * * @{ */ /************************************************************************************/ /** * \fn CHAN_INDEX MID_SIUTIL_CollectAllSections(GL_Queue_t hDmxEventQueueHdl, INT32 iTimeout) * * \param hDmxEventQueueHdl : event queue handle * \param iTimeout : time of time out * * \return index of channel handle which section is collected completely * * \note Description : * give some ids and get the index of channel array. * ************************************************************************************/ CHAN_INDEX MID_SIUTIL_CollectAllSections(GL_Queue_t hDmxEventQueueHdl, INT32 iTimeout); /************************************************************************************/ /** * \fn INT32 MID_SIUTIL_CollectSections(CHAN_INDEX index, INT32 iTimeout) * * \param index : indicate which channel we want to collect * \param iTimeout : time of time out * * \return 0 for success. -1 for failed * * \note Description : * collect the specific demux channel sections, other dmx channel use the same demux event queue handle will be released. * ************************************************************************************/ INT32 MID_SIUTIL_CollectSections(CHAN_INDEX index, INT32 iTimeout); /************************************************************************************/ /** * \fn INT32 MID_SIUTIL_CollectSectionsNonBlock(CHAN_INDEX index) * * \param index : indicate which channel we want to collect * * \return 0 for success. -1 for failed * * \note Description : * collect the specific demux channel sections without time out. * ************************************************************************************/ INT32 MID_SIUTIL_CollectSectionsNonBlock(CHAN_INDEX index); /************************************************************************************/ /** * \fn INT32 MID_SIUTIL_CollectSingleSection(CHAN_INDEX index, INT32 iTimeout, UINT8 **ppSec) * * \param index : indicate which channel we want to collect * \param iTimeout : time of time out * \param ppSec : pointer to collected section data * * \return 0 for success. -1 for failed * * \note Description : * only collect the specific demux channel "singal section", other dmx channel use the same demux event queue handle will be released. * ************************************************************************************/ INT32 MID_SIUTIL_CollectSingleSection(CHAN_INDEX index, INT32 iTimeout, UINT8 **ppSec); /************************************************************************************/ /** * \fn void MID_SIUTIL_FreeSections(CHAN_INDEX *pindex) * * \param pindex : point to which channel we want to collect * * \return none * * \note Description : * free the section buffer in channel array * ************************************************************************************/ void MID_SIUTIL_FreeSections(CHAN_INDEX *pindex); /** @} end of addtogroup Section Operation */ /** \addtogroup Get_channel_information Get Channel Information * \brief index and channel handle transformation * @{ */ /************************************************************************************/ /** * \fn CHAN_INDEX MID_SIUTIL_GetChannelIndexEx( LIVE_INPUT_UNIT InputUnit, UINT16 pid, INT8 table_id, INT16 ext_id) * * \param InputUnit : primary or secondary demux * \param pid : pid of TS packet * \param table_id : table_id * \param ext_id:it indicates program_number, if table is PMT. * it indicates transport_stream_id, if table is PAT, SDT, NIT. * * \return index of channel handle array * * \note Description : * give some ids and get the index of channel array. * ************************************************************************************/ CHAN_INDEX MID_SIUTIL_GetChannelIndexEx(LIVE_INPUT_UNIT InputUnit, UINT16 pid, INT8 table_id, INT16 ext_id); /************************************************************************************/ /** * \fn CHAN_INDEX MID_SIUTIL_GetChannelIndex( UINT16 pid, INT8 table_id, INT16 ext_id) * * \param pid : pid of TS packet * \param table_id : table_id * \param ext_id:it indicates program_number, if table is PMT. * it indicates transport_stream_id, if table is PAT, SDT, NIT. * * \return index of channel handle array * * \note Description : * give some ids and get the index of channel array. * ************************************************************************************/ CHAN_INDEX MID_SIUTIL_GetChannelIndex(UINT16 pid, INT8 table_id, INT16 ext_id); /************************************************************************************/ /** * \fn LP_MID_SiutilChannels_t MID_SIUTIL_TurnIndexToChannel(CHAN_INDEX index) * * \param index : channel index * * \return channel handle * * \note Description : * give a index and get the channel handle of array * ************************************************************************************/ LP_MID_SiutilChannels_t MID_SIUTIL_TurnIndexToChannel(CHAN_INDEX index); /** @} end of addtogroup Get Channel information */ /** \addtogroup Open_channels Open Channels * \brief open channels to map all tables in * @{ */ /************************************************************************************/ /** * \fn MID_SIUTIL_OpenChannelEx(LIVE_INPUT_UNIT InputUnit, * UINT16 pid, * INT8 table_id, * INT16 ext_id, * GL_Queue_t hChanEventQueueHdl, * MID_SIUTIL_CRC_CHECK eCrcCheck, * bool bIsMultiSection); * * \param InputUnit : primary or secondary demux * \param pid : pid of TS packet * \param table_id : table_id * \param ext_id:it indicates program_number, if table is PMT. * it indicates transport_stream_id, if table is PAT, SDT, NIT. * \param hChanEventQueueHdl : event queue handle * \param eCrcCheck : it indicate whether check CRC32 or not * * \return index of channel handle array * * \note Description : give some pids whick we want to map in. * ************************************************************************************/ CHAN_INDEX MID_SIUTIL_OpenChannelEx(LIVE_INPUT_UNIT InputUnit, UINT16 pid, INT8 table_id, INT16 ext_id, GL_Queue_t hChanEventQueueHdl, MID_SIUTIL_CRC_CHECK eCrcCheck, bool bIsMultiSection); //[kiwi 20090223] Add for TOT TDT /************************************************************************************/ /** * \fn MID_SIUTIL_OpenChannel(UINT16 pid, * INT8 table_id, * INT16 ext_id, * GL_Queue_t hChanEventQueueHdl, * MID_SIUTIL_CRC_CHECK eCrcCheck, * bool bIsMultiSection); * * \param pid : pid of TS packet * \param table_id : table_id * \param ext_id:it indicates program_number, if table is PMT. * it indicates transport_stream_id, if table is PAT, SDT, NIT. * \param hChanEventQueueHdl : event queue handle * \param eCrcCheck : it indicate whether check CRC32 or not * * \return index of channel handle array * * \note Description : give some pids whick we want to map in. * ************************************************************************************/ CHAN_INDEX MID_SIUTIL_OpenChannel( UINT16 pid, INT8 table_id, INT16 ext_id, GL_Queue_t hChanEventQueueHdl, MID_SIUTIL_CRC_CHECK eCrcCheck, bool bIsMultiSection); //[kiwi 20090223] Add for TOT TDT /************************************************************************************/ /** * \fn void MID_SIUTIL_CloseChannel(INT16 *pindex) * * \param pindex : point to which channel we want to close * * \return none * ************************************************************************************/ void MID_SIUTIL_CloseChannel(INT16 *pindex); /** \addtogroup Get_service_or_descriptor Get service or descriptor * @{ */ /************************************************************************************/ /** * \fn INT32 MID_SIUTIL_ServiceInArray(UINT16 *p_service, INT16 serLen, UINT16 serNum) * * \brief check whether the value serNum is in array p_service * * \param p_service : point to head of array * \param serLen : length of array * \param serNum : the value we want to check * * \return 0 for success, -1 for failed * ************************************************************************************/ INT32 MID_SIUTIL_ServiceInArray(UINT16 *p_service, INT16 serLen, UINT16 serNum); /* Add by anzhao, 2006/05/26 */ /************************************************************************************/ /** * \fn INT32 MID_SIUTIL_TagsInDescriptorArray(UINT8 *p_desc, * INT16 descLen, * UINT8 *pBytes, * UINT16 sDescrLoopLen) * * \brief Count the number of descriptors we want * * \param p_desc : Defined array of descriptor we want * \param descLen : Number of unit in descriptor array * \param pBytes : Source data of descriptor * \param sDescrLoopLen : Length of descriptor source * * \return number of descriptors we want in source data * ************************************************************************************/ INT32 MID_SIUTIL_TagsInDescriptorArray(UINT8 *p_desc, INT16 descLen, UINT8 *pBytes, UINT16 sDescrLoopLen); /************************************************************************************/ /** * \fn UINT8* MID_SIUTIL_CreateDescriptorArray(UINT8 *p_desc, * INT16 descLen, * UINT8 *pBytes, * UINT16 sDescrLoopLen, * UINT16 *bufLen) * * \brief Extract descriptors we want into a new array * * \param p_desc : Defined array of descriptor we want * \param descLen : Number of unit in descriptor array * \param pBytes : Source data of descriptor * \param sDescrLoopLen : Length of descriptor source * \param bufLen : It indicate that received length of new array * * \return Length(bytes) of new array * ************************************************************************************/ UINT8* MID_SIUTIL_CreateDescriptorArray(UINT8 *p_desc, INT16 descLen, UINT8 *pBytes, UINT16 sDescrLoopLen, UINT16 *bufLen); /** @} end of addtogroup Get service or descriptor */ /** \addtogroup Change_channel_value Change Channel Value * @{ */ /************************************************************************************/ /** * \fn INT32 MID_SIUTIL_ChangePsiChnFilter(CHAN_INDEX ChnIndex, * UINT8 FilterLen, * UINT8* Match, * UINT8* Mask, * UINT8* Negate) * * \brief Change filter of channel with this index * * \param ChnIndex : The index of channel array we want to change * \param FilterLen : total length of the filter we want to change * \param Match : indicate the value we want to match * \param Mask : indicate which bit we want to match * \param Negate : indicate the value we want to match using excusive or. * * \return 0 for success, -1 for failed * ************************************************************************************/ INT32 MID_SIUTIL_ChangePsiChnFilter(CHAN_INDEX ChnIndex, UINT8 FilterLen, UINT8 * Match, UINT8 * Mask, UINT8 * Negate, UINT8 * crc32, UINT8 bskip_conti_crc); /************************************************************************************/ /** * \fn CHAN_INDEX MID_SIUTIL_ChangePsiChnPID(CHAN_INDEX ChnIndex, * UINT8 FilterLen, * UINT16 prog_id, * UINT16 pid, * UINT8* Match, * UINT8* Mask, * UINT8* Negate, * MID_SIUTIL_CRC_CHECK eCrcCheck) * * \brief close the old channel and open a new one * * \param ChnIndex : The index of channel array we want to change * \param FilterLen : total length of the filter we want to change * \param prog_id : program_number * \param pid : PID * \param Match : indicate the value we want to match * \param Mask : indicate which bit we want to match * \param Negate : indicate the value we want to match using excusive or. * \param eCrcCheck : it indicate whether check CRC32 or not * * \return index of new channel handle * ************************************************************************************/ CHAN_INDEX MID_SIUTIL_ChangePsiChnPID(CHAN_INDEX ChnIndex, UINT8 FilterLen, UINT16 prog_id, UINT16 pid, MID_SIUTIL_CRC_CHECK eCrcCheck); /** @} end of addtogroup Change Channel Value */ /** \addtogroup Dump_buffer Dump Buffer * @{ */ /************************************************************************************/ /** * \fn void MID_SIUTIL_DumpBuffer(UINT8 *bBuffer, INT32 len) * * \brief dump buffer value * * \param bBuffer : pointer to head of buffer we want to dump * \param len : length of data we want to dump * * \return none * ************************************************************************************/ void MID_SIUTIL_DumpBuffer(UINT8 *bBuffer, INT32 len); MID_Status_t MID_SIUTIL_ReleaseDataInQueue(GL_Queue_t queueHdl); /** @} end of addtogroup Dump Buffer*/ #endif /* #ifndef _MID_SIUTIL_H_20080327 */