⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dvb_sibk.c

📁 DVB软件,基于CT216软件的开发源程序.
💻 C
字号:
#include <string.h>
#include <stdio.h>
#include "ct_type.h"
#include "ct_os.h"
#include "task_cfg.h"
#include "dvb_si.h"
#include "dvb_sys.h"
#include "dvb_sibk.h"

#if 0
	#define dprintf(P)  printf P
#else
	#define dprintf(P)
#endif

#define DVB_EITSIBK_ERROR_DEBUG
#ifdef DVB_EITSIBK_ERROR_DEBUG
	#define DB_ERR(p)      printf p
#else
	#define DB_ERR(p)
#endif  /* end #ifdef DVB_EITSIBK_ERROR_DEBUG */

//#define DVB_EITSIBK_LEVEL1_DEBUG
#ifdef DVB_EITSIBK_LEVEL1_DEBUG
	#define DB_L1(p)      printf p
#else
	#define DB_L1(p)
#endif  /* end #ifdef DVB_EITSIBK_LEVEL1_DEBUG */

//#define DVB_EITSIBK_LEVEL2_DEBUG
#ifdef DVB_EITSIBK_LEVEL2_DEBUG
	#define DB_L2(p)      printf p
#else
	#define DB_L2(p)
#endif  /* end #ifdef DVB_EITSIBK_LEVEL2_DEBUG */

//#define DVB_EITSIBK_PNT
#ifdef DVB_EITSIBK_PNT
	#define DB_PNT(p)      printf p
#else
	#define DB_PNT(p)
#endif  /* end #ifdef DVB_EITSIBK_PMT */

//#define DVB_EITSIBK_MGT
#ifdef DVB_EITSIBK_MGT
	#define DB_MGT(p)      printf p
#else
	#define DB_MGT(p)
#endif  /* end #ifdef DVB_EITSIBK_MGT */

#define MAX_TP_SERVICE_NUM 				100
#define VERSION_MASK					0x3E

typedef enum
{
	EN_SIBK_NONE,
	EN_SIBK_LOOKING_FOR_STATUS,
	EN_SIBK_FOUND_STAUS
} EN_SIBK_FINDING_STAUTS;

typedef struct  
{
	u16 	u16ServiceID; 		/* service id */
    u16 	u16PIDOfPMT; 		/* the pid of PMT */
	u8  	*pu8SectionBuffer; 	/* pmt section buffer */
} ST_PMT_INFO_T;

typedef struct  
{
	bool8			bCalled;
	u8  			u8NumOfServices;    			/* number of services in the PAT */
	u8				u8CatchedCount;
	u8				u8Version;
	u16 			u16OrgNID;
	u16 			u16TPID;						/* transport stream id */
	u16 			u16CurrentSrvID;
	u32 			u32CRC;
	ST_PMT_INFO_T 	aSTPMTInfo[MAX_TP_SERVICE_NUM]; 	
} ST_PAT_INFO_T;

#ifdef ATSC_SYSTEM
typedef struct  
{
	u8				u8Version;	
	u8  			u8NumOfEIT;    			/* number of EIT in the MGT */
	u8  			u8NumOfETT;    			/* number of ETT in the MGT */
	u32 			u32CatchTime;
	ST_PSIP_TABLE_INFO *pstMGTPSIP;
} ST_MGT_INFO_T;
#endif /* end #ifdef ATSC_SYSTEM */

#define MAX_MONITOR_CB_NUM							10
#define DVB_SIBK_WAIT_4_S			(4000/CTOS_MS_PER_TICKS)   // 1 tick = 10 ms
#define TDT_SECTION_LENGTH 			(8+4)
#define TOT_SECTION_LENGTH 			(200)

typedef struct  
{
	u8 				bContinues;						/* continue or one shot */
    u16 			u16ServiceID; 					/* service id */
	u8  			*pu8CBSectionBuffer; 				/* should be allocated by caller */
	void 			(*pfCallBack)(ST_SIBK_DVB_SI stDVBSITripleID, EN_FILTER_STATUS enStatus);	
} ST_SIBK_REGISTER_INFO_T;

typedef struct  
{
	u8 				u8FilterID;						/* filter ID */
    u16 			u16ServiceID; 					/* service id */
} ST_SIBK_FILTER_INFO_T;

typedef enum
{
	SIBK_PAT = 0, 				/* PAT */
    SIBK_PMT,					/* PMT */
#ifdef ATSC_SYSTEM
	SIBK_MGT,
	SIBK_TVCT,
	SIBK_STT,
#else /* else #ifdef ATSC_SYSTEM */   
    SIBK_TDT,					/* TDT */
    SIBK_TOT,					/* TOT */
#endif /* end #ifdef ATSC_SYSTEM */  
    SIBK_NUM_TABLE_TYPE			/* MAX TYPE */
}EN_SIBK_TABLE_TYPE;

static u8 u8RegisterNo = 0;
static ST_SIBK_REGISTER_INFO_T 	astPMTMonitorInfo[MAX_MONITOR_CB_NUM];
static ST_SIBK_FILTER_INFO_T	astSIBKFilterInfo[SIBK_NUM_TABLE_TYPE];
static ST_PAT_INFO_T 			stPATInfo;

static EN_SIBK_TASK_STATE		enSIBKTaskState = EN_SIBK_TASK_STOP;
static bool8 					bEnterMoniterMode = FALSE;
static CTOS_SEMAPHORE 	    	SIBKAccess_Sem;

static u16 						u32SIBKTimeout = 7000; 
static CTOS_QUEUE 				stSIBKMsgQueue;
static MSG_PARAMETER			stSIBKSendMsg;

#ifdef ATSC_SYSTEM
#define MAX_EIT_SET_NO			(128)
u8 au8STTSection[SECTION_1K]; /* PAT section buffer */
u8 au8MGTSection[SECTION_4K]; /* PAT section buffer */
ST_MGT_INFO_T stMGTInfo;
#if 0 // test only
bool8 b8MGTTest = FALSE;
#endif /* end if 0 */
#else
static u8 au8TDT[TDT_SECTION_LENGTH]={0,0,0,0,0,0,0,0,0,0,0,0};/*{0,0,0,0,0,0,0,0};*/
static u8 au8TOT[TOT_SECTION_LENGTH];
#endif

static ST_SIBK_DVB_SI stDVBSITripleID;

static u8 u8FID = 0xff;
//static CTOS_SEMAPHORE ctosSecMorSemaphore;

#if (defined (CI_ENABLE)||defined (CONAX))
static u16	u16CurrentServiceID;
#endif

#ifdef AP_SEARCH_TDT_TIME

extern CTOS_SEMAPHORE ctTDTSem;
extern CTOS_SEMAPHORE ctTDTWriteSem;

#endif

CTOS_TASK						stDVBSIBKTask;
u8 								u8DVBSIBKTaskStack [DVB_SIBK_TASK_STACK_SIZE];

u8 au8PATSection[SECTION_1K]; /* PAT section buffer */
u8 au8PMTSection[SECTION_1K]; /* PMT section buffer */

static void sibkclear (void);

#ifdef PVR_ENABLE
#ifdef CI_ENABLE
#include "dvb_pvr.h"
static void checkScrambledServiceInRecord(void);
#endif
#endif

/* DVB_SIBK_MonitorPMTRegister (void) */

EN_SIBK_STATUS DVB_SIBK_MonitorPMTRegister (void (*cbfunc) (ST_SIBK_DVB_SI stDVBSITripleID, EN_FILTER_STATUS enStatus), 
	u8 u8Type, u16 u16ServiceID, u8* pu8SectionBuffer, u16 u16SectionLeng)
/*! \fn DVB_SIBK_MonitorPMTRegister (void (*cbfunc) (EN_FILTER_STATUS enStatus), 
	u8 u8Type, u16 u16ServiceID, u8* pu8SectionBuffer, u16 u16SectionLeng)
\param cbfunc : callback function 
\param u8Type : indicate continue callback or not 
\param u16ServiceID : indicate the service id of PMT
\param pu8SectionBuffer : buffer saves the PMT section. Will be allocated by caller 
\param * PMTMonitor [10] to record these information 
*/
{
	u8 u8i = 0;
	EN_SIBK_STATUS status = EN_SIBK_NO_ERROR;
	
	if (!pu8SectionBuffer)
	{
		DB_ERR (("{DVB_SIBK_MonitorPMTRegister} return null section\n");)
		return EN_SIBK_ERROR;	
	}	
	
	if (u16SectionLeng < SECTION_1K)
	{
		DB_ERR (("{DVB_SIBK_MonitorPMTRegister} return section is too short u16SectionLeng][%d]\n",
			u16SectionLeng);)
		return EN_SIBK_ERROR;	
	}	
	dprintf (("{DVB_SIBK_MonitorPMTRegister} u8RegisterNo[%d] u16ServiceID[0x%x] u8Type[%d]\n", 
		u8RegisterNo, u16ServiceID, u8Type);)
	if (u8RegisterNo < (MAX_MONITOR_CB_NUM - 2))
	{
		u8RegisterNo ++;
	}
	else
	{
		DB_ERR (("{DVB_SIBK_MonitorPMTRegister} return register too much\n");)
		return EN_SIBK_ERROR;
	}		
	
	CT_OS_WaitOnSemaphore (&SIBKAccess_Sem, CTOS_WAIT);
	/* find a free slot */
	for (u8i = 0; u8i < MAX_MONITOR_CB_NUM; u8i ++)
	{
		if ((astPMTMonitorInfo[u8i].pfCallBack == NULL)
			&& astPMTMonitorInfo[u8i].pu8CBSectionBuffer == NULL)
		{	
			astPMTMonitorInfo[u8i].bContinues = u8Type;
			astPMTMonitorInfo[u8i].u16ServiceID = u16ServiceID;
			astPMTMonitorInfo[u8i].pu8CBSectionBuffer = pu8SectionBuffer;
			astPMTMonitorInfo[u8i].pfCallBack = cbfunc; 
			dprintf (("!!!!register idx[%d] num[%d] sid[0x%x] con[%d] cbsec[0x%x] pfc[0x%x]\n", 
				u8i, u8RegisterNo, astPMTMonitorInfo[u8i].u16ServiceID,
				astPMTMonitorInfo[u8i].bContinues, (int)astPMTMonitorInfo[u8i].pu8CBSectionBuffer, 
				(int)astPMTMonitorInfo[u8i].pfCallBack);)

			break;			
		}	
	}
	CT_OS_FreeSemaphore (&SIBKAccess_Sem);
	
	
	if ((u8i < MAX_MONITOR_CB_NUM) && (u8Type == FALSE))
	{
		/* one shot */
		stSIBKSendMsg.u8Cmd = EN_SIBK_PMT_REQ;
		stSIBKSendMsg.unData.u32MsgData = stPATInfo.u16CurrentSrvID;
		
		CT_OS_PutMsg (&stSIBKMsgQueue, &stSIBKSendMsg, CTOS_NO_WAIT);
	}

	return status; 
}

EN_SIBK_STATUS DVB_SIBK_MonitorPMTUnRegister (void (*cbfunc) (ST_SIBK_DVB_SI stDVBSITripleID, EN_FILTER_STATUS enStatus))
/*! \fn Dextern EN_SIBK_STATUS DVB_SIBK_MonitorPMTUnRegister (void (*cbfunc) (EN_FILTER_STATUS enStatus))
\param cbfunc : callback function 
\return EN_SIBK_STATUS see definition.
*/
{
	u8 u8j = 0;
	
	CT_OS_WaitOnSemaphore (&SIBKAccess_Sem, CTOS_WAIT);
	
	for (u8j = 0; u8j < MAX_MONITOR_CB_NUM; u8j ++)
	{
		if (cbfunc == astPMTMonitorInfo[u8j].pfCallBack)
		{
			astPMTMonitorInfo[u8j].pfCallBack = NULL;
			astPMTMonitorInfo[u8j].bContinues = FALSE;
			astPMTMonitorInfo[u8j].pu8CBSectionBuffer = NULL;
			astPMTMonitorInfo[u8j].u16ServiceID = INVALID_SI_ID;
			u8RegisterNo --;
			break;
		}
	}
	
	CT_OS_FreeSemaphore (&SIBKAccess_Sem);
	
	return EN_SIBK_NO_ERROR;
}	


EN_SIBK_STATUS DVB_SIBK_CHSwitchPreprocess (void)
{
	CT_OS_WaitOnSemaphore (&SIBKAccess_Sem, CTOS_WAIT);
	sibkclear ();
	CT_OS_FreeSemaphore (&SIBKAccess_Sem);
	return EN_SIBK_NO_ERROR; 
}

	
#ifdef PVR_ENABLE
#ifdef CI_ENABLE
static u8 u8PVRCICHSwitch = 0;
#endif
#endif
EN_SIBK_STATUS DVB_SIBK_CHSwitchNotify (ST_SIBK_DVB_SI stDVBSITripleID, bool8 bTPChanged)
/*! \fn DVB_SIBK_CHSwitchNotify (u16 u16ServiceID, bool8 bTPChanged)
\param u16ServiceID : indicate the service id of current watching channel 
\param bTPChanged : indicate TP change or not 
\param his function will be called while switch channel. 
\param If bTPChanged = TRUE, Send EN_SIBK_NEW_PAT_REQ 
       bTPChanged = FALSE,  Send EN_SIBK_NEW_PMT_REQ
*/
{
	if ((enSIBKTaskState == EN_SIBK_TASK_STOP) || (enSIBKTaskState == EN_SIBK_TASK_TIME_ONLY))
	{
		return EN_SIBK_ERROR;
	}
	
	CT_OS_WaitOnSemaphore (&SIBKAccess_Sem, CTOS_WAIT);	
	/* reset new current watching service id */
	if (bTPChanged == TRUE)
	{
		bEnterMoniterMode = FALSE;
		stPATInfo.u32CRC = stPATInfo.u8CatchedCount = 0;
	}
	

	stPATInfo.u16OrgNID = stDVBSITripleID.u16OrgNID;
	stPATInfo.u16TPID = stDVBSITripleID.u16TPID;
	stPATInfo.u16CurrentSrvID = stDVBSITripleID.u16ServiceID;
	DB_L2 (("SwitchNotify SID[0x%x] TPID[0x%x] OrgNID[0x%x] bTPChanged[%d]\n", 	
		stPATInfo.u16CurrentSrvID, stPATInfo.u16TPID, stPATInfo.u16OrgNID, bTPChanged);) 		
	
#if (defined (CI_ENABLE)||defined (CONAX))
	u16CurrentServiceID = stPATInfo.u16CurrentSrvID;
#endif

	stPATInfo.bCalled = FALSE;
	if (!stPATInfo.u8NumOfServices)
	{
		/* fource bTPChanged to TRUE */
		bTPChanged = TRUE;
	}	
	CT_OS_FreeSemaphore (&SIBKAccess_Sem);

	dprintf (("!!!{DVB_SIBK_CHSwitchNotify} time[0x%x] u16ServiceID[0x%x] bTPChanged[%d]\n",
		(int) DVB_TimerGet (), stPATInfo.u16CurrentSrvID, bTPChanged);)
	
	if (bTPChanged == TRUE)  
	{
		stSIBKSendMsg.u8Cmd = EN_SIBK_NEW_PAT_REQ;
		CT_OS_PutMsg (&stSIBKMsgQueue, &stSIBKSendMsg, CTOS_NO_WAIT);
	}
	else
	{
		stSIBKSendMsg.u8Cmd = EN_SIBK_NEW_PMT_REQ;

		stSIBKSendMsg.unData.u32MsgData = stPATInfo.u16CurrentSrvID;	
		
		CT_OS_PutMsg (&stSIBKMsgQueue, &stSIBKSendMsg, CTOS_NO_WAIT);

#ifdef PVR_ENABLE
#ifdef CI_ENABLE
		//锣

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -