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

📄 dvb_filt.c

📁 DVB软件,基于CT216软件的开发源程序.
💻 C
📖 第 1 页 / 共 5 页
字号:
	memset (&stMatch, 0xff, sizeof(DVB_SectionHeader));
	memset (&stMask,  0xff, sizeof(DVB_SectionHeader));	//<--- MaskBit = 1 means don't care

	if (u16TableID != DONT_CARE_TABLE_ID)			//1.table id pattern
	{
		stMatch.u8TableID = u16TableID;
		stMask.u8TableID = 0x00;
	}
	if(u32TableIDExtension != DONT_CARE_SUB_TABLE_ID)		//2.sub table id pattern
	{
		stMatch.u16SubTableID = u32TableIDExtension;
    	stMask.u16SubTableID = 0x0000;
	}
	if(u16SectionNum != DONT_CARE_SECTION_NUM)		//3.section number pattern
	{
		stMatch.u8SectionNumber = u16SectionNum;
		stMask.u8SectionNumber = 0x00;
	}
	
	/* skip : stMatch.au8ExtendIDs[0] is protocal_version */ 
	if (u16SourceID != DONT_CARE_SOURCE_ID)
	{
		stMatch.au8ExtendIDs[1] = ((u16SourceID >>8)& 0xff);
		stMask.au8ExtendIDs[1] = 0x00;
		stMatch.au8ExtendIDs[2] = ((u16SourceID >>0)& 0xff);
		stMask.au8ExtendIDs[2] = 0x00;
	}	
	
	dvb_filterset (*pu8FID, u16PID, &stMask, &stMatch, sec_cb);
	/* reset fifo of the filter */
	dvb_filtercleanbuffer (*pu8FID);
	/* start the filter */
	dvb_filterstart (*pu8FID, u16TimeoutMilliSec, FALSE);
//	FILT_DBG(( "{DVB_SectionMonitorPSIP} u16PID[0x%x] TableID[0x%x], u32TableIDExtension[0x%x] *pu8FID[0x%x]\n",
//		u16PID, u16TableID, u32TableIDExtension, *pu8FID));

//FILT_DBG( ("{DVB_PSIPSecMonitor} u16PID[0x%x] TableID[0x%x] u32TableIDExtension[0x%x] *pu8FID[0x%x]\n",
//		u16PID, u16TableID, u32TableIDExtension, *pu8FID));
    CT_OS_FreeSemaphore (&DVBFilterSemaphore);
	return (EN_FILTER_NO_ERROR);
}
#endif /* end if ATSC_SYSTEM */

static bool8 dvb_filtercheckavailablesection (u8 u8FID)
{
	if (u8FID >= MAX_FILTER_NUMBER)
	{
		return (FALSE);
	}

	if (astSectionFilter[u8FID].u8AvailableSection)
	{
		return (TRUE);
	}
	else
	{
		return (FALSE);
	}
}

bool8 DVB_FilterCheckAvailableSection (u8 u8FID)
{
	bool8 b8result;

	CT_OS_WaitOnSemaphore (&DVBFilterSemaphore, CTOS_WAIT);
	b8result = dvb_filtercheckavailablesection (u8FID);
	CT_OS_FreeSemaphore (&DVBFilterSemaphore);
	return b8result;
}

/*! \fn EN_FILTER_STATUS DVB_SectionGet (u16 u16PID, u16 u16TableID, u32 u32SubTableID, u16 u16SectionNum, u8* pu8Section, u16 u16MaxSecSize, u16 u16TimeoutMilliSec)
\brief Synchronous function, get a specific section, check CRC and close filter automatic.
\param u16PID (Input) PID for this section.
\param u16TableID (Input) table ID for this section.
\param u32SubTableID (Input) sub-table ID for this section.
\param u16SectionNum (Input) section number for this section.
\param pu8Section (Output) a buffer point to get section.
\param u16MaxSecSize (Input) max length of receiver buffer.
\param u16TimeoutMilliSec (Input) timeout in milli-second, or using TIMEOUT_INFINITE.
\return EN_FILTER_STATUS reference define.
*/
EN_FILTER_STATUS DVB_SectionGet (u16 u16PID, u16 u16TableID, u32 u32SubTableID, u16 u16SectionNum,
	u8* pu8Section, u16 u16MaxSecSize, u16 u16TimeoutMilliSec)
{
	u8 u8FID;
	DVB_SectionHeader stMatch, stMask;
	EN_FILTER_STATUS enStatus=EN_FILTER_NO_ERROR;
    u8 u8CrcErrorCounter;

	/* check parameter */
	if (pu8Section == NULL)
	{
		return(EN_FILTER_ERROR);
	}
    CT_OS_WaitOnSemaphore (&DVBFilterSemaphore, CTOS_WAIT);
	/* open a free filter */
	gen_point = 102;
	u8FID = dvb_filteropen (RING_BUFFER_SIZE_8K);
	if(u8FID==INVALID_FILTER_ID)
	{
		FILT_DBG( ("DVB_SectionGet retrn FAIL because error filter \n"));
		CT_OS_FreeSemaphore (&DVBFilterSemaphore);
		return(EN_FILTER_ERROR);
	}

	/*set the filter */
	memset(&stMatch, 0xff, sizeof(DVB_SectionHeader));
	memset(&stMask,  0xff, sizeof(DVB_SectionHeader));	//<--- MaskBit = 1 means don't care

	if(u16TableID!=DONT_CARE_TABLE_ID)			//1.table id
	{
		stMatch.u8TableID=u16TableID;
    	stMask .u8TableID=0x00;
	}
	if(u32SubTableID!=DONT_CARE_SUB_TABLE_ID)	//2.sub table id
	{
		stMatch.u16SubTableID=u32SubTableID;
	    stMask .u16SubTableID=0x0000;
	}
	if(u16SectionNum!=DONT_CARE_SECTION_NUM)		//3.section number
	{
		stMatch.u8SectionNumber=u16SectionNum;
		stMask.u8SectionNumber=0x00;
	}

	/* set the filter mask and match */
	dvb_filterset (u8FID, u16PID, &stMask, &stMatch, NULL);

	/* reset fifo of the filter */
	dvb_filtercleanbuffer(u8FID);
	
	/* start the filter */
	dvb_filterstart (u8FID, u16TimeoutMilliSec, TRUE);

	/* get section */
	u8CrcErrorCounter = 0;
	
	while(TRUE)
	{
		/* check time out condition */
		
		if(dvb_filterchecktimeout(u8FID))
		{
			FILT_DBG(("\n>> DVB_SectionGet() : dvb_filterchecktimeout \n"));
			enStatus = EN_FILTER_TIMEOUT;
			break;
		}

		/* check got section or not */
		if(dvb_filtercheckavailablesection(u8FID)== TRUE)
		{
			/* copy section from fifo to dram */
			if(dvb_filtergetsection(u8FID, pu8Section, u16MaxSecSize)==FALSE)	//failed
			{
				enStatus = EN_FILTER_ERROR;
				break;
			}

			/* check crc */
			if (DVB_FilterCheckCRC32(pu8Section)== TRUE)
			{
				enStatus = EN_FILTER_SECTION_AVAILABLE;
				break;
			}
			else
			{
		        u8CrcErrorCounter++;
			    enStatus = EN_FILTER_CRC_ERROR;
			    if(u8CrcErrorCounter>6)
			    {
    			    break;
    			}
    			else
    			{
    				/* restart */
    			    dvb_filterstop(u8FID);
    				dvb_filterstart(u8FID, u16TimeoutMilliSec, TRUE);
                    FILT_DBG(("DVB_FILT: CRC error retry %hx\n", u8CrcErrorCounter));
			    }
			}
		}
		
		CT_OS_FreeSemaphore (&DVBFilterSemaphore);
		CT_OS_Delay (DVB_FILTER_WAIT_10_MS);
		CT_OS_WaitOnSemaphore (&DVBFilterSemaphore, CTOS_WAIT);
		
	}

	/* close the filter */
	dvb_filterclose (u8FID);
    CT_OS_FreeSemaphore (&DVBFilterSemaphore);
	return(enStatus);
}

bool8 DVB_FilterCheckCRC32 (u8* pu8Section)
{
	u16 u16SecLenInByte;

	/* get section length from buffer */
	u16SecLenInByte  = ((*(pu8Section+1)&0x0f)<<8);
	u16SecLenInByte |= ((*(pu8Section+2)&0xff)<<0);

	if (u16SecLenInByte <= 4)
	{
		FILT_DBG( ("CRC -- return false because wrong length\n"));
		return(FALSE);
	}
	u16SecLenInByte = u16SecLenInByte + 3; //plus before section length fields

	/* check CRC */
	if (!CT_DEMUX_CRC32Check(pu8Section,u16SecLenInByte))	//<---return 0 means CRC correct
	{
		return (TRUE);
	}
	else
	{
		FILT_DBG( ("CRC -- return false\n"));
		return (FALSE);
	}

}
static bool8 _filtergetsection (u8 u8FID, u8* pu8Section, u16 u16MaxLength)
{
	u8 u8Buffer[4];
	MSG_PARAMETER		stDFSendMsg;
    u16 u16SecLenInByte = 0;
#if !(defined (CT216U)||defined (CT956))
    u16 u16SecLenInLong;
#endif

	if (CT_FILT_PeekData (astSectionFilter[u8FID].u32SecFltNo, u8Buffer, 4) != DRV_OK)
	{
		FILT_DBG(( "{dvb_filtergetsection} call CT_FILT_PeekData FAIL u8FID[0x%x]\n",u8FID));
		return (FALSE);
	}
	/* get section length */
	u16SecLenInByte = ((u8Buffer[1]&0x0f) << 8);
	u16SecLenInByte |= ((u8Buffer[2]&0xff) << 0);

	//FILT_DBG( ("u16SecLenInByte[0x%x]\n", u16SecLenInByte));
	if (u16SecLenInByte > 0)
	{
		u16SecLenInByte += 3;
	}
	else
	{
		FILT_DBG(("{dvb_filtergetsection} FAIL total section length = %d \n", (int)u16SecLenInByte));
		return(FALSE);	//<--- Invalid section length
	}
	if (u16SecLenInByte > u16MaxLength)
	{
		FILT_DBG(("{dvb_filtergetsection} u8FID[0x%x] section buffer is too short[%d] need[%d]\n",
			u8FID, u16MaxLength, u16SecLenInByte + 3));
		return(FALSE);
	}
#if !(defined (CT216U)||defined (CT956))
	u16SecLenInLong = u16SecLenInByte/4;
	if ((u16SecLenInByte % 4) !=0)
	{
		u16SecLenInLong +=1;
	}
#endif
	/*[04]copy from fifo to dram ============================================*/	
#if (defined (CT216U)||defined (CT956))   
	if (CT_FILT_GetData(astSectionFilter[u8FID].u32SecFltNo, pu8Section, u16SecLenInByte) == DRV_OK)
#else
	if (CT_FILT_GetData(astSectionFilter[u8FID].u32SecFltNo, pu8Section, u16SecLenInLong*4) == DRV_OK)
#endif
	{
		if(astSectionFilter[u8FID].u8AvailableSection==0)
		{
			if(CT_FILT_GetBufferFullness(astSectionFilter[u8FID].u32SecFltNo)>0)
			{              
				//astSectionFilter[u8FID].u8AvailableSection++;	// move to Moninter Task
				stDFSendMsg.u8Cmd               = u8FID;
				stDFSendMsg.unData.u32MsgData   = (u32)DVB_FILTER_MSG_DATA_INCREASE_AVAILABLE_NUM;
				CT_OS_PutMsg(&stDFQueue, &stDFSendMsg, CTOS_NO_WAIT);            
			}
		}
		return (TRUE);
	}
	else
	{
		dvb_filterstop (u8FID);
		dvb_filterstart (u8FID, astSectionFilter[u8FID].u16TimeoutMilliSec, astSectionFilter[u8FID].b8OneShot);
		return(FALSE);
	}
}	
static bool8 dvb_filtergetsection (u8 u8FID, u8* pu8Section, u16 u16MaxLength)
{
#if 0	
	u8 u8Buffer[4];
	MSG_PARAMETER		stDFSendMsg;
    u16 u16SecLenInByte = 0;
#if !(defined (CT216U)||defined (CT956))
    u16 u16SecLenInLong;
#endif
#endif // end if 0

	/* check parameter and status */
	if ((u8FID >= MAX_FILTER_NUMBER)
		|| (astSectionFilter[u8FID].b8Allocated == FALSE)
		|| (pu8Section == NULL))
	{
		FILT_DBG(( "{dvb_filtergetsection} FAIL u8FID[0x%x] b8Allocated[0x%x]\n",
			u8FID, astSectionFilter[u8FID].b8Allocated));
		return (FALSE);
	}
	/* section is not available yet */
	if(!astSectionFilter[u8FID].u8AvailableSection)
	{
		FILT_DBG(( "{dvb_filtergetsection} FAIL u8FID[0x%x] u8AvailableSection[0x%x]\n",
			u8FID, astSectionFilter[u8FID].u8AvailableSection));
		return (FALSE);
	}
    astSectionFilter[u8FID].u8AvailableSection --;

#if 1
	return (_filtergetsection (u8FID, pu8Section, u16MaxLength));
#else // !1
	if (CT_FILT_PeekData (astSectionFilter[u8FID].u32SecFltNo, u8Buffer, 4) != DRV_OK)
	{
		FILT_DBG(( "{dvb_filtergetsection} call CT_FILT_PeekData FAIL u8FID[0x%x]\n",u8FID));
		return (FALSE);
	}
	/* get section length */
	u16SecLenInByte = ((u8Buffer[1]&0x0f) << 8);
	u16SecLenInByte |= ((u8Buffer[2]&0xff) << 0);

	//FILT_DBG( ("u16SecLenInByte[0x%x]\n", u16SecLenInByte));
	if (u16SecLenInByte > 0)
	{
		u16SecLenInByte += 3;
	}
	else
	{
		FILT_DBG(("{dvb_filtergetsection} FAIL total section length = %d \n", (int)u16SecLenInByte));
		return(FALSE);	//<--- Invalid section length
	}
	if (u16SecLenInByte > u16MaxLength)
	{
		FILT_DBG(("{dvb_filtergetsection} u8FID[0x%x] section buffer is too short[%d] need[%d]\n",
			u8FID, u16MaxLength, u16SecLenInByte + 3));
		return(FALSE);
	}
#if !(defined (CT216U)||defined (CT956))
	u16SecLenInLong = u16SecLenInByte/4;
	if ((u16SecLenInByte % 4) !=0)
	{
		u16SecLenInLong +=1;
	}
#endif
	/*[04]copy from fifo to dram ============================================*/	
#if (defined (CT216U)||defined (CT956))   
	if (CT_FILT_GetData(astSectionFilter[u8FID].u32SecFltNo, pu8Section, u16SecLenInByte) == DRV_OK)
#else
	if (CT_FILT_GetData(astSectionFilter[u8FID].u32SecFltNo, pu8Section, u16SecLenInLong*4) == DRV_OK)
#endif
	{
		if(astSectionFilter[u8FID].u8AvailableSection==0)
		{
			if(CT_FILT_GetBufferFullness(astSectionFilter[u8FID].u32SecFltNo)>0)
			{              
				//astSectionFilter[u8FID].u8AvailableSection++;	// move to Moninter Task
				stDFSendMsg.u8Cmd               = u8FID;
				stDFSendMsg.unData.u32MsgData   = (u32)DVB_FILTER_MSG_DATA_INCREASE_AVAILABLE_NUM;
				CT_OS_PutMsg(&stDFQueue, &stDFSendMsg, CTOS_NO_WAIT);            
			}
		}
		return (TRUE);
	}
	else
	{
		dvb_filterstop (u8FID);
		dvb_filterstart (u8FID, astSectionFilter[u8FID].u16TimeoutMilliSec, astSectionFilter[u8FID].b8OneShot);
		return(FALSE);
	}
#endif // end #if 1	
}

/*! \fn bool8 DVB_FilterGetSection (u8 u8FID, u8* pu8Section, u16 u16MaxLength)
\brief Get section in section buffer of some filter.
\param u8FID (Input) get section from which circular buffer.
\param pu8Section (Input) a point to section buffer.
\param u16MaxLength (Input) max length of receiver buffer.
\return TRUE - got a section.
\return FALSE - no available section or wrong parameters.
*/
bool8 DVB_FilterGetSection (u8 u8FID, u8* pu8Section, u16 u16MaxLength) // channel_id is better
{
	bool8 b8result;

	CT_OS_WaitOnSemaphore (&DVBFilterSemaphore, CTOS_WAIT);
	b8result = dvb_filtergetsection (u8FID, pu8Section, u16MaxLength);
	CT_OS_FreeSemaphore (&DVBFilterSemaphore);
	return b8result;
}

⌨️ 快捷键说明

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