📄 cas.c
字号:
/****************************************************************************
*
* ALi
*
* File: cas.c
*
* Description:
*
* History:
* Date Author Version Comment
* ==== ====== ======= =======
*
*
****************************************************************************/
#include <sys_config.h> //Type of Sys Tuner Board Flash Eeprom
#include <types.h> // UINT16 UINT32 NULL INT8 INT16 INT32
#include <osal/osal.h> // Osal Func
#include <api/libc/printf.h> // Lib C for printf
#include <api/libc/string.h> // Lib C for string
#include <hld/hld_dev.h> // IO Parameter
#include <hld/dmx/dmx_dev.h> // Strut of Stream
#include <hld/dmx/dmx.h> // Strut of Stream and Device
#include <api/libtsi/si_monitor.h> // SI Info
#include <api/libpub27/lib_pub27.h> // NIM Func ON and OFF
#include "system_data.h" // Maintain system config data
#include "ap_root.h" // Mpeg Sat Menu
#include "api/libtcpip/arch/cc.h" // Memset Define
#include <hld/nim/nim_dev.h> // Nim Tuner Func
#include <api/libdiseqc/lib_diseqc.h> // Diseq Func
#include "win_com_popup.h" // STB Main Menu Window Display and Respond Key of Remote
#include "osd_config.h" // OSD Func
#include "cas.h" // Debug Cas
//#include "emu.h"
#include "keydata.h" // Define Caid's and Strut of Him Max is 7 Cas
#include "tps.h" // TPS Bin old mode
//#define CAS_DEBUG
#define CAS_DUMP(data,len) {\
const int l=(len); int i;\
CAS_DEBUG_PRINTF(" CAS_DUMP \n");\
for(i=0; i<l ; i++)\
{\
if((i!=0) && ((i&0x0F) == 0)) CAS_DEBUG_PRINTF("\n");\
CAS_DEBUG_PRINTF("%02x ",*((data)+i));\
}\
CAS_DEBUG_PRINTF("\n");\
}
#define FILTER_VALUE_EMM_8ALL "\x80\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
#define FILTER_MASK_EMM_8ALL "\xF0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
#define FILTER_VALUE_CAT "\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
#define FILTER_MASK_CAT "\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
#define FILTER_VALUE_ECM "\x80\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
#define FILTER_MASK_ECM "\xFE\x80\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
/*Viaccess*/
#define FILTER_VALUE_EMM_V8C "\x8C\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
#define FILTER_MASK_EMM_V8C "\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
#define FILTER_VALUE_EMM_V87 "\x87\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
#define FILTER_MASK_EMM_V87 "\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
#define FILTER_VALUE_EMM_V8ALL "\x80\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
#define FILTER_MASK_EMM_V8ALL "\xF0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
#define FILTER_VALUE_EMM_V8D "\x8D\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
#define FILTER_MASK_EMM_V8D "\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
#define FILTER_VALUE_EMM_V8E "\x8E\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
#define FILTER_MASK_EMM_V8E "\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
/*Nagra1, section_id=0x82; Nagra2 section_id=0x82&0x83*/
#define FILTER_VALUE_EMM_N "\x82\0\0\0\0\0\0\0\0\x4B\0\0\0\0\0\0"
#define FILTER_MASK_EMM_N "\xFE\0\0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\0\0\0\0\0\0"
/*Irdeto, section_id=0x82*/
#define FILTER_VALUE_EMM_I "\x82\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
#define FILTER_MASK_EMM_I "\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
/*SECA, section_id=0x84*/
#define FILTER_VALUE_EMM_S "\x84\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
#define FILTER_MASK_EMM_S "\xFF\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
//#define NEWPATCH_DEBUG
#define BISS_DEBUG
#ifdef NEWPATCH_DEBUG
#define PATCH2_PRINTF(...) do{}while(0)
#define PATCH_PRINTF libc_printf
#else
#define PATCH_PRINTF(...) do{}while(0)
#define PATCH2_PRINTF(...) do{}while(0)
#endif
#ifdef BISS_DEBUG
#define BISS_PRINTF libc_printf
#else
#define BISS_PRINTF(...) do{}while(0)
#endif
/************************
Declare
*************************/
void cas_main_thread(UINT32 param1, UINT32 param2);
/************************
Define golable variable
*************************/
static cas_t cas;
static struct cc_xpond_info cur_tp_xpond;
UINT16 emm_caid=0;
UINT32 cur_provide_id=0;
void pmt_section_callback(UINT8 *section, INT32 length, UINT16 param);
static void write_cw(struct dmx_device *dmx_dev, UINT8 *dcw, UINT8 resend);
#define FILTER_MASK_LEN 0x10
#define SECTION_BUFFER_SIZE 4096
// static UINT8 *cas_buff = NULL;
#define MAX_CMT_LENGTH 4096//256
static UINT8 ecm_buffer[MAX_CMT_LENGTH];
static UINT8 emm_buffer[MAX_CMT_LENGTH];
static UINT8 cat_buffer[SECTION_BUFFER_SIZE];
static UINT8 ecm_tab_id = 0xFF; // static
/***************************
cas intreface
****************************/
INT32 api_cas_register(void (*callback)(enum cas_msg_type type))
{
OSAL_T_CTSK t_ctsk;
OSAL_T_CMBF t_cmbf;
PATCH_PRINTF("api_cas_register running !!!\n");
MEMSET(&cas, 0, sizeof(cas_t));
cas.callback = NULL;//callback;
/* create cas massage buffer */
t_cmbf.bufsz = 0x800;
t_cmbf.maxmsz = 16;
cas.msgque_id = osal_msgqueue_create(&t_cmbf);
if (OSAL_INVALID_ID == cas.msgque_id)
{
PATCH_PRINTF("Can not create cas message buffer!!!\n");
ASSERT(0);
}
/* create cas_emu thread */
t_ctsk.task = (OSAL_T_TASK_FUNC_PTR)cas_main_thread;
t_ctsk.itskpri = OSAL_PRI_NORMAL;
t_ctsk.stksz = 0x1000;
t_ctsk.quantum = 10;
t_ctsk.name[0] = 'C';
t_ctsk.name[1] = 'A';
t_ctsk.name[2] = 'S';
cas.thread_id = osal_task_create(&t_ctsk);
if (OSAL_INVALID_ID == cas.thread_id)
{
PATCH_PRINTF("Can not create cas main thread!!!\n");
ASSERT(0);
}
//cas_buff = (UINT8 *)MALLOC(0x1000);
//if(cas_buff == NULL)
// {
// CAS_ERROR_PRINTF("Can not malloc cas_buff !\n");
// ASSERT(0);
// }
// MEMSET(cas_buff, 0, 0x1000);
// api_cas_mem_read(cas_buff, 0x1000);
si_monitor_register_pmt_cb((section_parse_cb_t)pmt_section_callback);
cas.state = CAS_STATE_IDLE;
return RET_SUCCESS;
}
INT32 api_cas_unregister()
{
/* delete cas_emu thread */
osal_task_delete(cas.thread_id);
/* delete cas_emu massage buffer */
osal_msgqueue_delete(cas.msgque_id);
cas.callback = NULL;
cas.state = CAS_STATE_UNREGISTER;
return RET_SUCCESS;
}
UINT8 need_pmt = 0;
INT32 api_cas_start()
{
need_pmt = 1;
// api_cas_mem_read(cas_buff, 0x1000);
}
INT32 api_cas_stop()
{
api_cas_send_msg(CAS_MSG_STOP, 0);
return RET_SUCCESS;
}
void api_cas_send_msg(enum cas_msg_type type, UINT32 param)
{
cas_msg_t msg;
msg.type = type;
msg.param = param;
osal_msgqueue_send(cas.msgque_id, &msg, sizeof(cas_msg_t), OSAL_WAIT_FOREVER_TIME);
}
INT32 sync_get_ecm_section(UINT16 ecm_pid, UINT8 *ecm_buffer, UINT16 buffer_size)
{
RET_CODE ret;
struct dmx_device *dmx_dev;
struct restrict ecm_restrict;
struct get_section_param ecm_section_param;
dmx_dev = (struct dmx_device *)dev_get_by_type(NULL, HLD_DEV_TYPE_DMX);
if(dmx_dev == NULL)
{
CAS_ERROR_PRINTF("Dev_get_by_type error!\n");
return !RET_SUCCESS;
}
MEMSET(&ecm_restrict, 0, sizeof(struct restrict));
ecm_restrict.value_num = 1;
ecm_restrict.mask_len = 2;
ecm_restrict.mask[0] = 0xFE;
ecm_restrict.value[0][0] = 0x80;
ecm_restrict.mask[1] = 0x80;
ecm_restrict.value[0][1] = 0;
MEMSET(&ecm_section_param, 0, sizeof(struct get_section_param));
ecm_section_param.pid = ecm_pid;
ecm_section_param.buff = ecm_buffer;
ecm_section_param.buff_len = buffer_size;
ecm_section_param.crc_flag = 0;
ecm_section_param.mask_value = &ecm_restrict;
ecm_section_param.wai_flg_dly = 20000;
ret = dmx_req_section(dmx_dev, &ecm_section_param);
return ret;
}
/*************************************
cas_filter_poller
**************************************/
void filter_get_sec_cb(struct get_section_param *gsp)
{
#if 0
filter_msg_t msg;
section_buffer_t *sec_buf = NULL;
UINT8 *section_buffer = gsp->buff;
UINT16 pid = gsp->pid;
PATCH_PRINTF("PID:%08x\n", pid);
UINT8 index = (filter_sec_buf.write_index + 1) % FILTER_SECTION_BUFFER_NUM;
if(index != filter_sec_buf.read_index)
{
PATCH_PRINTF("wi %d\n", index);
filter_sec_buf.write_index = index;
sec_buf = &(filter_sec_buf.buffer[index]);
sec_buf->section_pid = pid;
MEMCPY(sec_buf->section_buffer, section_buffer, ((UINT16)((section_buffer[1]&0x0F)|section_buffer[2]))+3);
msg.type = FILTER_GOT_SECTION;
msg.param = 0;
osal_msgqueue_send(filter_msgque, &msg, sizeof(filter_msg_t), OSAL_WAIT_FOREVER_TIME);
}
#else
PATCH_PRINTF("PID:%04x\n", gsp->pid);
#endif
}
#define FILTER_STATE_IDLE 0
#define FILTER_STATE_READY 1
#define FILTER_STATE_BUSY 2
#define FILTER_STATE_TIMEOUT 3
/*
IDLE---->(create)READY---->(start)BUSY
(close)<---- (stop)<----
*/
typedef void (*filter_handler_t)(UINT8 *content, UINT16 va_length);
typedef struct {
INT8 filter;
UINT8 filter_status;
UINT32 last_time;
struct restrict filter_restrict;
struct get_section_param filter_section;
filter_handler_t filter_handler;
} cas_filter_t;
typedef INT8 cas_filter_id;
#define ERROR_FILTER_ID -1
#define CAS_MAX_FILTER_NUMBER 8
cas_filter_t cas_filter[CAS_MAX_FILTER_NUMBER];
static INT32 cas_filter_init()
{
UINT8 i;
MEMSET(&cas_filter, 0, sizeof(cas_filter));
for(i=0; i<CAS_MAX_FILTER_NUMBER; i++)
{
cas_filter[i].filter_status = FILTER_STATE_IDLE;
cas_filter[i].filter = -1;
}
return RET_SUCCESS;
}
static cas_filter_id cas_filter_create(UINT16 pid, filter_handler_t function)
{
cas_filter_t *filter = NULL;
UINT8 *section_buff = NULL;
INT8 i;
for(i=0; i<CAS_MAX_FILTER_NUMBER; i++)
{
if (cas_filter[i].filter_status == FILTER_STATE_IDLE)
{
filter = &(cas_filter[i]);
break;
}
}
if(filter == NULL)
{
CAS_ERROR_PRINTF("Filter list is full!\n");
return ERROR_FILTER_ID;
}
section_buff = (UINT8 *)MALLOC(SECTION_BUFFER_SIZE);
if(section_buff == NULL)
{
CAS_ERROR_PRINTF("Malloc error!\n");
return ERROR_FILTER_ID;
}
MEMSET(section_buff, 0, SECTION_BUFFER_SIZE);
filter->filter = -1;
filter->filter_status = FILTER_STATE_READY;
filter->filter_section.pid = pid;
filter->filter_section.buff = section_buff;
filter->filter_section.buff_len = SECTION_BUFFER_SIZE;
filter->filter_section.crc_flag = 0;
filter->filter_section.mask_value = &(filter->filter_restrict);
filter->filter_section.wai_flg_dly = OSAL_WAIT_FOREVER_TIME;
filter->filter_section.get_sec_cb = filter_get_sec_cb;
filter->filter_section.continue_get_sec = 0;
filter->filter_handler = function;
return i;
}
static INT32 cas_filter_setpid(cas_filter_id filter_id, UINT16 pid)
{
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]);
filter->filter_section.pid = pid;
}
static INT32 cas_filter_setfilterparams(cas_filter_id filter_id, UINT8 *mask, UINT8 *value)
{
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((mask == NULL) || (value == 0))
{
CAS_ERROR_PRINTF("Error params\n");
return !RET_SUCCESS;
}
MEMSET(&(filter->filter_restrict), 0, sizeof(struct restrict));
filter->filter_restrict.value_num = 1;
filter->filter_restrict.mask_len = FILTER_MASK_LEN;
MEMCPY(&(filter->filter_restrict.mask), mask, FILTER_MASK_LEN);
MEMCPY(&(filter->filter_restrict.value[0]), value, FILTER_MASK_LEN);
return RET_SUCCESS;
}
static INT32 cas_filter_start(struct dmx_device *dmx_dev, cas_filter_id filter_id)
{
RET_CODE ret;
cas_filter_t *filter = NULL;
if(filter_id == ERROR_FILTER_ID)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -