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