📄 dvb_sibk.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 + -