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

📄 dvb_caecm.c

📁 我国有线电视条件接受标准目前还没有统一
💻 C
字号:
#include <stdio.h>#include <string.h>#include <stdlib.h>#include <cyg/io/io.h>#include <cyg/hal/types.h>#include <cyg/infra/diag.h>#include <cyg/kernel/kapi.h>#include "custom.h"#include "kinf.h"#include "message_id.h"#include "mbuf_ext_data.h"#include "dvb_module.h"#include "sp_demux.h"#include "DVB_CADemux.h"#include "dvb_ca.h"#include "DVB_CAEcm.h"#include "DVB_CAService.h"#include "sys_setup.h"static ST_ECM g_astEcm[MAX_ECM_NUM];static ST_CA_DEMUX g_astEcmDemux[MAX_ECM_NUM];static UINT8 g_ucEcmBuffer[MAX_ECM_NUM][MAX_ECM_SECTION_LEN];static cyg_mutex_t g_CAECMMutex;static S_HLCAPack g_stEcmPacket;#if defined(SDT_CA_50)static UINT8 g_aucCW[MAX_ECM_NUM][3][8];static UINT8 g_aucCWSum[MAX_ECM_NUM];static UINT8 g_aucTableID[MAX_ECM_NUM];static UINT8 g_ucVideoIdx = 0;static UINT16 g_usProductID = 0xFFFF;static UINT8 g_ucOSDView = 0;static UINT8 g_ucProgramLevel = 0;static UINT8 g_ucFingerprint = 0;#endif#define CA_ECM_DEBUGextern INT32 sp_DemuxProgramDescrambleKey(UINT32 keyIdx, UINT32 oddEvenKey, UINT8 * key);extern INT32 sp_DemuxSetChannelDescrambleKeyIndex(UINT32 dwChannel, UINT32 keyIdx);extern void DVB_CAEMM_UpdateTime(S_Time *pstTime);static void DVB_CAECM_SetCW(S_ECM *pstCW, ST_ECM *pstEcm);static void DumpCw(UINT8 *pucBuffer, int iIndex);#if defined(SDT_CA_50)static void DVB_CA_ECM_ParseEcm(S_ECM *pstEcm, ST_ECM *pstEcmData);void DVB_CAECM_ResetOsdView(void){	cyg_mutex_lock(&g_CAECMMutex);		g_ucOSDView = 0;	cyg_mutex_unlock(&g_CAECMMutex);	}void DVB_CAECM_ResetFingerPrintf(void){	cyg_mutex_lock(&g_CAECMMutex);		g_ucFingerprint = 0;	cyg_mutex_unlock(&g_CAECMMutex);	}UINT8 DVB_CAECM_GetFingerPrint(void){	return g_ucFingerprint;}UINT8 DVB_CAECM_GetOsdView(void){	return g_ucOSDView;}UINT16 DVB_CAECM_GetProductID(void){	return g_usProductID;}UINT8 DVB_CAECM_CheckProgrowLevel(void){	UINT32 uiLevel = 0;	SYSSET_Get(PWDCFG_LEVEL, (UINT32 *)(&uiLevel));	if(uiLevel + g_ucProgramLevel <= 7)		return 0;	else		return 1;}#endifvoid DVB_CAECM_Init(void){	cyg_mutex_init(&g_CAECMMutex);}void DVB_CAECM_UnInit(void){	cyg_mutex_destroy(&g_CAECMMutex);}void DVB_CAECM_Start(UINT16 *pusPid, UINT8 *pucChanIdx, UINT8 ucEcmNum){	int i,j;		cyg_mutex_lock(&g_CAECMMutex);		memset(g_astEcm, 0x0, MAX_ECM_NUM * sizeof(ST_ECM));	memset(g_astEcmDemux, 0x0, MAX_ECM_NUM * sizeof(ST_CA_DEMUX));	memset(g_ucEcmBuffer, 0x0, MAX_ECM_NUM * MAX_ECM_SECTION_LEN);	for(i = 0; i < ucEcmNum; i++)	{		if(pusPid[i] == 0x1FFF)			continue;					for(j = 0; j < i; j++)		{			if(g_astEcm[j].ucInUsed == 0)				break;			if(pusPid[i] == g_astEcm[j].usPid)				break;		}		g_astEcm[j].ucTableID = 0xFF;		g_astEcm[j].ucKeyIndex = j;		g_astEcm[j].usPid = pusPid[i];		g_astEcm[j].ucInUsed = 1;		g_astEcm[j].aucChanIndex[g_astEcm[j].ucChanNum] = pucChanIdx[i];		g_astEcm[j].ucChanNum++;		#if defined(SDT_CA_50)		if(i == 0)			g_ucVideoIdx = j;		#endif	}			for(i = 0; i < MAX_ECM_NUM; i++)	{		if(g_astEcm[i].ucInUsed == 0)			break;		g_astEcmDemux[i].iChannelIndex = -1;		g_astEcmDemux[i].pucDemuxBuffer = g_ucEcmBuffer[i];		g_astEcmDemux[i].ucType = CHANNEL_TYPE_PSI;		g_astEcmDemux[i].usMaxBufferLen = MAX_ECM_BUFFER_LEN;		g_astEcmDemux[i].usMaxSectionLen = MAX_ECM_SECTION_LEN;		g_astEcmDemux[i].usPid = g_astEcm[i].usPid;		g_astEcmDemux[i].ucNoCrc = 1;		g_astEcmDemux[i].ucMatch[0][0] = 0x80;							g_astEcmDemux[i].ucMask[0][0] = 0xFE;		g_astEcmDemux[i].ucFilterLen[0] = 1;		g_astEcmDemux[i].ucFilterNum = 1;		DVB_CAOpenChannel(&(g_astEcmDemux[i]));	}		#if defined(SDT_CA_50)	g_usProductID = 0xFFFF;	g_ucProgramLevel = 0;	memset(g_aucCW, 0x0, MAX_ECM_NUM * 3 * 8);	memset(g_aucCWSum, 0x0, MAX_ECM_NUM );	#endif	cyg_mutex_unlock(&g_CAECMMutex);	}void DVB_CAECM_Stop(void){	int i;	cyg_mutex_lock(&g_CAECMMutex);		for(i = 0; i < MAX_ECM_NUM; i++)	{		if(g_astEcm[i].ucInUsed == 0)			break;		if( g_astEcmDemux[i].iChannelIndex >= 0)		{			DVB_CACloseChannel(&(g_astEcmDemux[i]));		}	}	#if defined(SDT_CA_50)	g_usProductID = 0xFFFF;	g_ucProgramLevel = 0;	memset(g_aucCW, 0x0, MAX_ECM_NUM * 3 * 8);	memset(g_aucCWSum, 0x0, MAX_ECM_NUM );	#endif	memset(g_astEcm, 0x0, MAX_ECM_NUM * sizeof(ST_ECM));	memset(g_astEcmDemux, 0x0, MAX_ECM_NUM * sizeof(ST_CA_DEMUX));	memset(g_ucEcmBuffer, 0x0, MAX_ECM_NUM * MAX_ECM_SECTION_LEN);		cyg_mutex_unlock(&g_CAECMMutex);	}void DVB_CAECM_Clear(int iChannel){	UINT8 aucCw[8];	memset(aucCw, 0x0, 8);	cyg_mutex_lock(&g_CAECMMutex);		sp_DemuxProgramDescrambleKey(iChannel, 0, aucCw);	sp_DemuxProgramDescrambleKey(iChannel, 1, aucCw);	cyg_mutex_unlock(&g_CAECMMutex);	}void MemoryTest(void){	UINT8 *pTemp = NULL;	int i = 1;	while(1)	{		pTemp = (UINT8 *)malloc(i *10*1024);		if(pTemp == NULL)		{			break;		}		free(pTemp);		pTemp = NULL;		i++;	}	ecos_printf("Max:%d\n", (i-1)* 10 *1024);}void DVB_CAECM_Polling(void){	int i;	#if defined(SDT_CA_50)	int j;	#endif	int iResult = 0;	cyg_mutex_lock(&g_CAECMMutex);		for(i = 0; i < MAX_ECM_NUM; i++)	{		if(g_astEcm[i].ucInUsed == 0)			break;		if(g_astEcmDemux[i].iChannelIndex < 0)		{			DVB_CAOpenChannel(&(g_astEcmDemux[i]));		}		else		{			iResult = DVB_CADemuxReadSection(&(g_astEcmDemux[i]));						if(iResult == DEMUX_SUCCESS)			{					g_astEcm[i].ucTableID = g_astEcmDemux[i].pucDemuxBuffer[0] & 0xFF;				memset(&g_stEcmPacket, 0x0, sizeof(S_HLCAPack));				HLCA_ParsePack(g_astEcmDemux[i].pucDemuxBuffer, &g_stEcmPacket);				if(g_stEcmPacket.EMMType == ECM)				{					#if defined(SDT_CA_40)					DVB_CAECM_SetCW(&(g_stEcmPacket.contents.ECM), &(g_astEcm[i]));					#elif defined(SDT_CA_50)										g_aucCWSum[i] = g_stEcmPacket.contents.ECM.CW_sum;					g_aucTableID[i] = g_astEcm[i].ucTableID;					for(j = 0; j < g_aucCWSum[i]; j++)					{						memcpy(g_aucCW[i][j], g_stEcmPacket.contents.ECM.s_CW[j].cw, 8);					}					DVB_CA_ECM_ParseEcm(&(g_stEcmPacket.contents.ECM), &(g_astEcm[i]));					#endif										DVB_CACloseChannel(&(g_astEcmDemux[i]));					if(g_astEcm[i].ucTableID == 0x80)						g_astEcmDemux[i].ucMatch[0][0] = 0x81;					else						g_astEcmDemux[i].ucMatch[0][0] = 0x80;											g_astEcmDemux[i].ucMask[0][0] = 0xFF;					g_astEcmDemux[i].ucFilterLen[0] = 1;					DVB_CAOpenChannel(&(g_astEcmDemux[i]));									}				HLCA_FreeMem(&g_stEcmPacket, g_stEcmPacket.EMMType);			}			else if(iResult == DEMUX_ERROR)			{				DVB_CACloseChannel(&(g_astEcmDemux[i]));				DVB_CAOpenChannel(&(g_astEcmDemux[i]));			}					}	}	cyg_mutex_unlock(&g_CAECMMutex);	}#if defined(SDT_CA_50)void DVB_CAECM_ResetCw(void){	int i,j;	cyg_mutex_lock(&g_CAECMMutex);	for(i = 0; i < MAX_ECM_NUM; i++)	{		if(g_astEcm[i].ucInUsed == 0)			break;		if(g_aucCWSum[i]== 0)			continue;		if(g_aucCWSum[i] < 2)		{			DumpCw(g_aucCW[i][0], 0);			if(g_aucTableID[i] & 0x01)				sp_DemuxProgramDescrambleKey(g_astEcm[i].ucKeyIndex, 0x00, g_aucCW[i][0]);			else				sp_DemuxProgramDescrambleKey(g_astEcm[i].ucKeyIndex, 0x01, g_aucCW[i][0]);			}		else		{			DumpCw(g_aucCW[i][g_aucCWSum[i] -2], 0);			if(g_aucTableID[i] & 0x01)				sp_DemuxProgramDescrambleKey(g_astEcm[i].ucKeyIndex, 0, g_aucCW[i][g_aucCWSum[i] -2]);			else				sp_DemuxProgramDescrambleKey(g_astEcm[i].ucKeyIndex, 1, g_aucCW[i][g_aucCWSum[i] -2]);			DumpCw(g_aucCW[i][g_aucCWSum[i] -1], 1);			if(g_aucTableID[i] & 0x01)				sp_DemuxProgramDescrambleKey(g_astEcm[i].ucKeyIndex, 1, g_aucCW[i][g_aucCWSum[i] -1]);			else				sp_DemuxProgramDescrambleKey(g_astEcm[i].ucKeyIndex, 0, g_aucCW[i][g_aucCWSum[i] -1]);		}		for(j = 0; j < g_astEcm[i].ucChanNum ; j++)		{			sp_DemuxSetChannelDescrambleKeyIndex(g_astEcm[i].aucChanIndex[j],g_astEcm[i].ucKeyIndex);		}	}	cyg_mutex_unlock(&g_CAECMMutex);}static void DVB_CA_ECM_ParseEcm(S_ECM *pstEcm, ST_ECM *pstEcmData){	int iNewScrambled = 1;	int iOldScrambled = 0;	main_prog_msg_t stMsg;	UINT8 ucMessage ;		if(pstEcm == NULL)		return;	DVB_CAEMM_UpdateTime(&(pstEcm->currentTime));		if(g_ucVideoIdx == pstEcmData->ucKeyIndex)	{		g_usProductID = pstEcm->s_Ctrl.Product_ID;		g_ucProgramLevel = pstEcm->s_Ctrl.Program_level;		if(g_ucFingerprint != pstEcm->s_Ctrl.Fingerprint_View)		{			g_ucFingerprint = pstEcm->s_Ctrl.Fingerprint_View;			ucMessage = CA_SHOW_CARD;			stMsg.u8MsgID   	= DVB_MODULE_ID;			stMsg.u8SubModID = CA_UI_ID;			stMsg.u16FuncID  	= CA_MESSAGE;			stMsg.pData = (void *)&ucMessage;			DVB_SendBackMsg(&stMsg, 1);		}		if(pstEcm->s_Ctrl.OSD_View != g_ucOSDView)		{			g_ucOSDView = pstEcm->s_Ctrl.OSD_View;			ucMessage = CA_CHECK_MSG;			stMsg.u8MsgID   	= DVB_MODULE_ID;			stMsg.u8SubModID = CA_UI_ID;			stMsg.u16FuncID  	= CA_MESSAGE;			stMsg.pData = (void *)&ucMessage;			DVB_SendBackMsg(&stMsg, 1);		}			}	if(DVB_CAService_CheckPrograme(pstEcm->s_Ctrl.Product_ID) == 0 && DVB_CAECM_CheckProgrowLevel() == 0)	{		DVB_CAECM_SetCW(pstEcm, pstEcmData);		iNewScrambled = 0;	}	iOldScrambled = DVBSUI_WarnMsg_GetScrambleType();	if((iNewScrambled == 0 && iOldScrambled != 0)		|| (iNewScrambled != 0 && iOldScrambled == 0))	{		ucMessage = CA_NEW_SERVICE;		stMsg.u8MsgID   	= DVB_MODULE_ID;		stMsg.u8SubModID = CA_UI_ID;		stMsg.u16FuncID  	= CA_MESSAGE;		stMsg.pData = (void *)&ucMessage;		DVB_SendBackMsg(&stMsg, 1);		if(iNewScrambled)		{			memset(&stMsg,0x0,sizeof(main_prog_msg_t));			stMsg.u8MsgID = DVB_MODULE_ID;			stMsg.u8SubModID = PLAYBACK_MODULE_ID;			stMsg.u16FuncID = DVB_Clear;			DispatchMsg(&stMsg,0);		}	}	}#endifstatic void DVB_CAECM_SetCW(S_ECM *pstCW, ST_ECM *pstEcm){	int i;	if(pstCW == NULL || pstEcm == NULL)		return;		#if defined(SDT_CA_40)	if(pstCW->cw_sum == 0)		return;	ecos_printf("tabled id:%d\n",pstEcm->ucTableID);	if(pstCW->cw_sum < 2)	{		DumpCw(pstCW->cw[0].cw, 0);		if(pstEcm->ucTableID & 0x01)			sp_DemuxProgramDescrambleKey(pstEcm->ucKeyIndex, 0x00, pstCW->cw[0].cw);		else			sp_DemuxProgramDescrambleKey(pstEcm->ucKeyIndex, 0x01, pstCW->cw[0].cw);		}	else	{		DumpCw(pstCW->cw[pstCW->cw_sum -2].cw, 0);		if(pstEcm->ucTableID & 0x01)			sp_DemuxProgramDescrambleKey(pstEcm->ucKeyIndex, 0, pstCW->cw[pstCW->cw_sum -2].cw);		else			sp_DemuxProgramDescrambleKey(pstEcm->ucKeyIndex, 1, pstCW->cw[pstCW->cw_sum -2].cw);		DumpCw(pstCW->cw[pstCW->cw_sum -1].cw, 1);		if(pstEcm->ucTableID & 0x01)			sp_DemuxProgramDescrambleKey(pstEcm->ucKeyIndex, 1, pstCW->cw[pstCW->cw_sum -1].cw);		else			sp_DemuxProgramDescrambleKey(pstEcm->ucKeyIndex, 0, pstCW->cw[pstCW->cw_sum -1].cw);	}	#elif defined(SDT_CA_50)	if(pstCW->CW_sum== 0)		return;	if(pstCW->CW_sum < 2)	{		DumpCw(pstCW->s_CW[0].cw, 0);		if(pstEcm->ucTableID & 0x01)			sp_DemuxProgramDescrambleKey(pstEcm->ucKeyIndex, 0x00, pstCW->s_CW[0].cw);		else			sp_DemuxProgramDescrambleKey(pstEcm->ucKeyIndex, 0x01, pstCW->s_CW[0].cw);		}	else	{		DumpCw(pstCW->s_CW[pstCW->CW_sum -2].cw, 0);		if(pstEcm->ucTableID & 0x01)			sp_DemuxProgramDescrambleKey(pstEcm->ucKeyIndex, 0, pstCW->s_CW[pstCW->CW_sum -2].cw);		else			sp_DemuxProgramDescrambleKey(pstEcm->ucKeyIndex, 1, pstCW->s_CW[pstCW->CW_sum -2].cw);		DumpCw(pstCW->s_CW[pstCW->CW_sum -1].cw, 1);		if(pstEcm->ucTableID & 0x01)			sp_DemuxProgramDescrambleKey(pstEcm->ucKeyIndex, 1, pstCW->s_CW[pstCW->CW_sum -1].cw);		else			sp_DemuxProgramDescrambleKey(pstEcm->ucKeyIndex, 0, pstCW->s_CW[pstCW->CW_sum -1].cw);	}	#endif	for(i = 0; i < pstEcm->ucChanNum ; i++)	{		sp_DemuxSetChannelDescrambleKeyIndex(pstEcm->aucChanIndex[i],pstEcm->ucKeyIndex);	}}static void DumpCw(UINT8 *pucBuffer, int iIndex){	#ifdef CA_ECM_DEBUG	int i;	if(iIndex == 0)		ecos_printf("\n");	ecos_printf("cw%d:", iIndex);	for(i = 0; i < 8; i++)		ecos_printf("0x%02x ",pucBuffer[i]);	ecos_printf("\n");	#endif}

⌨️ 快捷键说明

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