📄 dvb_filt.c
字号:
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 + -