📄 cas.c
字号:
{
CAS_ERROR_PRINTF("error filter\n");
return !RET_SUCCESS;
}
filter = &(cas_filter[filter_id]);
if(filter->filter_status == FILTER_STATE_BUSY)
return RET_SUCCESS;
if(filter->filter != -1)
{
dmx_io_control(dmx_dev, IO_ASYNC_CLOSE, filter->filter);
filter->filter = -1;
}
do
{
ret = dmx_async_req_section(dmx_dev, &(filter->filter_section), &(filter->filter));
if (ret == OSAL_E_OK)
break;
CAS_ERROR_PRINTF("Get filter error\n");
osal_task_sleep(100);
} while(ret != RET_SUCCESS);
filter->last_time = osal_get_tick();
filter->filter_status = FILTER_STATE_BUSY;
return RET_SUCCESS;
}
static INT32 cas_filter_stop(struct dmx_device *dmx_dev, cas_filter_id filter_id)
{
cas_filter_t *filter = NULL;
if(filter_id == ERROR_FILTER_ID)
{
CAS_ERROR_PRINTF("Error filter\n");
return !RET_SUCCESS;
}
filter = &(cas_filter[filter_id]);
if(filter->filter_status == FILTER_STATE_READY)
return RET_SUCCESS;
if(filter->filter != -1)
dmx_io_control(dmx_dev, IO_ASYNC_CLOSE, filter->filter);
filter->filter_status = FILTER_STATE_READY;
return RET_SUCCESS;
}
static INT32 cas_filter_close(cas_filter_id filter_id)
{
cas_filter_t *filter = NULL;
if(filter_id == ERROR_FILTER_ID)
{
CAS_ERROR_PRINTF("Error filter\n");
return !RET_SUCCESS;
}
filter = &(cas_filter[filter_id]);
if(filter->filter_status == FILTER_STATE_IDLE)
return RET_SUCCESS;
if(filter->filter_section.buff != NULL)
FREE(filter->filter_section.buff);
MEMSET(filter, 0, sizeof(cas_filter_t));
filter->filter_status = FILTER_STATE_IDLE;
filter->filter = -1;
return RET_SUCCESS;
}
static void cas_filter_poll(struct dmx_device *dmx_dev)
{
UINT8 i;
UINT32 stat;
UINT32 tick;
UINT32 dmx_param[2];
dmx_param[0] = 0xFFFFFFFF;
dmx_param[1] = 0;
cas_filter_t *filter = NULL;
stat = dmx_io_control(dmx_dev, IO_ASYNC_POLL, (UINT32)&dmx_param);
for(i=0; i<CAS_MAX_FILTER_NUMBER; i++)
{
filter = &(cas_filter[i]);
if (filter->filter_status == FILTER_STATE_BUSY)
{
if (stat&(1<<filter->filter))
{
if (filter->filter<5)
{
CAS_ERROR_PRINTF("Dangerours filter-%d\n", filter->filter);
}
else
{
dmx_io_control(dmx_dev, IO_ASYNC_CLOSE, filter->filter);
filter->filter = -1;
}
stat = dmx_io_control(dmx_dev, IO_ASYNC_POLL, (UINT32)&dmx_param);
if(filter->filter_handler != NULL)
{
UINT8 *section_buff = filter->filter_section.buff;
filter->filter_handler(section_buff, ((UINT16)((section_buff[1]&0x0F)<<8|section_buff[2]))+3);
}
filter->last_time = osal_get_tick();
if (dmx_async_req_section(dmx_dev, &(filter->filter_section), &(filter->filter)) != RET_SUCCESS)
{
CAS_ERROR_PRINTF("Request section error!\n");
}
}
else if((osal_get_tick() - filter->last_time) > filter->filter_section.wai_flg_dly) /*how to process overlap*/
{
if (filter->filter<5)
{
PRINTF("Dangerours filter-%d\n", filter->filter);
}
else
{
dmx_io_control(dmx_dev, IO_ASYNC_CLOSE, filter->filter);
filter->filter = -1;
}
stat = dmx_io_control(dmx_dev, IO_ASYNC_POLL, (UINT32)&dmx_param);
filter->filter_status = FILTER_STATE_TIMEOUT;
if (filter->filter_handler)
{
filter->filter_handler(NULL, 0);
}
filter->last_time = osal_get_tick();
filter->filter_status = FILTER_STATE_BUSY;
if (dmx_async_req_section(dmx_dev, &(filter->filter_section), &(filter->filter)) != RET_SUCCESS)
{
CAS_ERROR_PRINTF("Request section error!\n");
}
}
}
}
}
/*************************************
cas_info_manager
**************************************/
typedef struct
{
UINT16 ca_system_id;
UINT32 provide_id;
UINT16 ecm_pid;
UINT8 *data; //reserve for SECA, maybe useful
} ecm_info_t;
#define MAX_ECM_INFO 32
struct _cas_ecm_info
{
UINT8 total_num; /*total number*/
UINT8 active_index; /*active index*/
ecm_info_t cas_ecm[MAX_ECM_INFO];
} cas_ecm_info;
static INT32 cas_ecm_info_init()
{
MEMSET(&cas_ecm_info, 0, sizeof(cas_ecm_info));
}
static INT32 cas_ecm_info_add(UINT16 ca_system_id, UINT32 provide_id, UINT16 ecm_pid)
{
UINT i;
ecm_info_t *temp_ecm_info = NULL;
unsigned char testpro[3];
// PATCH_PRINTF("ddf Ecm info exist: ca:%04x, prov: %04x, ecm: %04x\n: %x, ", ca_system_id, provide_id, ecm_pid);
testpro[0]=(provide_id>>16)&0xff;
testpro[1]=(provide_id>>8)&0xff;
testpro[2]=provide_id&0xff;
for(i=0; i<cas_ecm_info.total_num; i++)
{
temp_ecm_info = &cas_ecm_info.cas_ecm[i];
if((temp_ecm_info->ca_system_id == ca_system_id) && (temp_ecm_info->provide_id == provide_id))
break;
}
if(i != cas_ecm_info.total_num)
{
temp_ecm_info->ecm_pid = ecm_pid;
PATCH_PRINTF("Ecm info exist: ca:%04x, prov: %04x, ecm: %04x\n %02x %02x %02x", ca_system_id, provide_id, ecm_pid,testpro[0],testpro[1],testpro[2]);
return RET_SUCCESS;
}
if(cas_ecm_info.total_num < MAX_ECM_INFO)
{
// if(ResetEcmSuccess(ca_system_id,testpro)==1)
{
temp_ecm_info = &cas_ecm_info.cas_ecm[cas_ecm_info.total_num];
temp_ecm_info->ca_system_id = ca_system_id;
temp_ecm_info->provide_id = provide_id;
temp_ecm_info->ecm_pid = ecm_pid;
cas_ecm_info.total_num ++;
PATCH_PRINTF("Ecm info add: ca:%04x, prov: %06, ecm: %04x\n: %x, ", ca_system_id, provide_id, ecm_pid);
return RET_SUCCESS;
}
}
else
{
PATCH_PRINTF("cas_cas_info has been filled\n");
return !RET_SUCCESS;
}
}
static INT32 cas_ecm_info_delete_all()
{
UINT8 i;
while(cas_ecm_info.total_num > 0)
{
MEMSET(&(cas_ecm_info.cas_ecm[cas_ecm_info.total_num-1]), 0, sizeof(ecm_info_t));
cas_ecm_info.total_num--;
}
return RET_SUCCESS;
}
static ecm_info_t *cas_ecm_info_get_active()
{
ecm_info_t *ecm_info = NULL;
if(cas_ecm_info.total_num > 0)
{
if(cas_ecm_info.active_index >= cas_ecm_info.total_num)
cas_ecm_info.active_index = 0;
ecm_info = &(cas_ecm_info.cas_ecm[cas_ecm_info.active_index]);
}
else
{
ecm_info = NULL;
}
return ecm_info;
}
#define CAS_INFO_SET_ACTIVE_NEXT 0
#define CAS_INFO_SET_ACTIVE_PREV 1
static INT32 cas_ecm_info_set_active(UINT8 type)
{
if(cas_ecm_info.total_num > 0)
{
switch(type)
{
case CAS_INFO_SET_ACTIVE_NEXT:
if(cas_ecm_info.active_index >= cas_ecm_info.total_num-1)
{
cas_ecm_info.active_index = cas_ecm_info.total_num-1;
CAS_ERROR_PRINTF("The last one, active_index = %d, num = %d\n", cas_ecm_info.active_index, cas_ecm_info.total_num);
return !RET_SUCCESS;
}
else
cas_ecm_info.active_index++;
break;
case CAS_INFO_SET_ACTIVE_PREV:
if(cas_ecm_info.active_index <= 0)
{
cas_ecm_info.active_index = 0;
CAS_ERROR_PRINTF("Fhe first one, active_index = %d, num = %d\n", cas_ecm_info.active_index, cas_ecm_info.total_num);
return !RET_SUCCESS;
}
else
cas_ecm_info.active_index--;
break;
}
return RET_SUCCESS;
}
else
{
CAS_ERROR_PRINTF("No cas_info_t \n");
return !RET_SUCCESS;
}
}
/*************************************
parse ca_descriptor
**************************************/
#define CA_SYSTEM_MASK 0xFF00
#define CA_SYSTEM_NAGRA 0x1800
#define CA_SYSTEM_NAGRA2 0x1801
#define CA_SYSTEM_VIACCESS 0x0500
#define CA_SYSTEM_SECA 0x0100
#define CA_SYSTEM_IRDETO 0x0600
#define CA_SYSTEM_BETA 0x1700
#define CA_SYSTEM_CONAX 0x0B00
#define CA_SYSTEM_BISS 0x2600
#define CA_SYSTEM_CRYPTOWORKS 0x0D00
// PMT will call this function
static void parse_ca_descriptor(UINT8 *buffer, UINT8 length, UINT16 prg_number)
{
UINT16 ca_system;
UINT32 provide_id = 0;
UINT16 ecm_pid;
UINT8 i;
INT32 ret;
int result=0;
unsigned char dcw[16];
static struct dmx_device *dmx_dev;
dmx_dev = (struct dmx_device *)dev_get_by_type(NULL, HLD_DEV_TYPE_DMX);
#if 1
int kk;
PATCH_PRINTF("parse_ca_descriptor buffer=");
for(kk=0;kk<length;kk++)
PATCH_PRINTF("%3x ",buffer[kk]);
PATCH_PRINTF("\n");
#endif
////////////////////////////////////////////////// hk_patch
ca_system = (buffer[0] <<8) | buffer[1];
PATCH_PRINTF(" get ca system id from PMT Table..... %x %x \n",ca_system,ca_system&0xFF00);
switch(ca_system&0xFF00)
{
case CA_SYSTEM_VIACCESS:
PATCH_PRINTF("ca_system: %x, ", ca_system);
ecm_pid = ((buffer[2]&0x1F) << 8) | buffer[3];
if(ecm_pid >= 0xAA && ecm_pid <= 0xCF)
{
PATCH_PRINTF("dropped \"fake\" ecm pid 0x%04x\n",ecm_pid);
break;
}
i = 4;
while (i < length)
{
if (buffer[i] == 0x14)
{
provide_id = (buffer[i+2]<<16)|(buffer[i+3]<<8)|(buffer[i+4]&0xF0);
PATCH_PRINTF("provide_id=%x, ecm_pid=%x \n", provide_id, ecm_pid);
cas_ecm_info_add(ca_system, provide_id, ecm_pid);
}
i += 2 + buffer[i+1];
}
break;
case CA_SYSTEM_SECA:
PATCH_PRINTF("ca_system: %x, ", ca_system);
for(i=2; i<length; i+=15)
{
ecm_pid = ((buffer[i]&0x1F) << 8) | buffer[i+1];
provide_id = (buffer[i+2] << 8) | buffer[i+3];
#if 0 //some private data
if(buffer[i+4] == 0xFF) private_data(&buffer[i+5], 10);
#endif
PATCH_PRINTF("provide_id=%x, ecm_pid=%x \n", provide_id, ecm_pid);
cas_ecm_info_add(ca_system, provide_id, ecm_pid);
}
break;
case CA_SYSTEM_IRDETO:
case CA_SYSTEM_BETA:
case CA_SYSTEM_CONAX:
case CA_SYSTEM_NAGRA:
case CA_SYSTEM_CRYPTOWORKS://add by zkc
//case CA_SYSTEM_BISS:
PATCH_PRINTF("ca_system: %x, ", ca_system);
ecm_pid = ((buffer[2]&0x1F) << 8) | buffer[3];
PATCH_PRINTF("Now ecm_pid=%x %04x\n", ecm_pid,ca_system);
cas_ecm_info_add(ca_system, provide_id, ecm_pid);
break;
#if 1
case CA_SYSTEM_BISS:
BISS_PRINTF("CA_SYSTEM_BISS: prg_number=0x%x\n",prg_number);
result = cas_handle_biss(prg_number, dcw);
if (result)
{
/* dcw : 18 AA 00 C2 C2 D3 28 BD 18 AA 00 C2 C2 D3 28 BD */
/* set dcw */
BISS_PRINTF("Happy!!!CA system open success,ca_system_id=0x%x\n",ca_system);
cas_set_dcw(dcw);
write_cw(dmx_dev, dcw, 1);
}
else
BISS_PRINTF("Sorry!!!Cannot open current CA system,ca_system_id=0x%x\n",ca_system);
break;
#endif
default:
if(ca_system&0xFF01 == CA_SYSTEM_NAGRA2)
{
PATCH_PRINTF("ca_system: %x, ", ca_system);
ecm_pid = ((buffer[2]&0x1F) << 8) | buffer[3];
cas_ecm_info_add(ca_system, provide_id, ecm_pid);
}
else
PATCH_PRINTF("unsupport ca system: %4x\n", ca_system);
break;
}
}
void pmt_section_callback(UINT8 *section, INT32 length, UINT16 param)
{
UINT16 index, prog_info_len,section_len,es_info_len;
UINT16 left_len;
UINT16 prg_number;
UINT16 prg_ECM_ID;
UINT8 *discriptor_pointer = NULL;
UINT8 *discriptor_pointer2 = NULL;
UINT8 loop_length;
UINT16 ca_discriptor_num;
int result;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -