📄 viaccess.c
字号:
via_consultation_answer(Handle,Response,0,&Read,Status,tmplen-1);
via_consultation_answer(Handle,Response+tmplen-1,0,&Read,Status,1);
}
}
/*-------------------------------------------------------------------*/
/* 函 数 名:via_get_cw */
/* 函数功能:发送ECM,读取控制字 */
/* 参 数:Handle: Smart卡句柄 */
/* pECM : ECM数据头指针 */
/* pCW : 读取的CW数据 */
/* 返 回 值:18 : 取的控制字的长度 */
/* -1 : 卡不支持此节目供应商 */
/* -2 : 要求输入密码 */
/* -3 : ECM已经发送,但不能解节目 */
/* -4 : 发送ECM数据响应信息出错 */
/* -5 : 读取控制字出错 */
/* 全局变量: */
/* 调用模块: */
/* 备 注: */
/*-------------------------------------------------------------------*/
static int via_get_cw(Smart_Handle_t Handle,
U8* pECM,
U8* pCW)
{
int tmp;
static U8 ins[5] = {0xca, 0xc0, 0x00, 0x00, 0x12};
int length;
U8 Status[2];
U8 file[3];
U8 Response[254];
U16 Read;
Smart_ErrorCode_t error;
/* if Card Not Prepared , return 0 */
length = (pECM[1] & 0x0F << 8) + pECM[2] + 3;
file[0] = pECM[6];
file[1] = pECM[7];
file[2] = pECM[8]&0xF0;
Status[0] = 0;
Status[1] = 0;
if(!via_select_file(Handle,file,Response,0,&Read,Status))
return -1;
pECM[4] = 0xCA;
pECM[5] = 0x88;
pECM[6] = 0x00;
pECM[7] = pECM[8] & 0x0F;
pECM[8] = length-9;
Status[0] = 0xFF;
Status[1] = 0xFF;
error = via_transfer(Handle,
pECM+4,
length-4,
Response,
&Read,
Status);
if(error != SMC_NO_ERROR)
return -7;
if(Status[0] == 0x98)
{
return -2;
}
else if(Status[1] == 0x08)
{
return -3;
}
else if(!((Status[0] == 0x90) && (Status[1] == 0x00)))
{
/* if procedure bytes is not 0x90 0x00,just flush the smart card and return -4 */
return -4;
}
Read = 0;
error = via_transfer(Handle,
ins,
5,
Response,
&Read,
Status);
if(error !=SMC_NO_ERROR)
{
return -7;
}
if(Read==18)
{
memcpy(pCW,Response,Read);
/* We have got control words,return the length of CW */
tmp = pCW[2]+pCW[3]+pCW[4];
pCW[5] = tmp&0xFF;
tmp = pCW[6]+pCW[7]+pCW[8];
pCW[9] = tmp&0xFF;
tmp = pCW[10]+pCW[11]+pCW[12];
pCW[13] = tmp&0xFF;
tmp = pCW[14]+pCW[15]+pCW[16];
pCW[17] = tmp&0xFF;
return Read;
}
else
{
/* if we can't get CW, return -5 */
return -5;
}
return -6;
}
/*-------------------------------------------------------------------*/
/* 函 数 名:via_parse_ecm */
/* 函数功能:处理ECM数据 */
/* 参 数:pbuf: Ecm数据头指针 */
/* 返 回 值: */
/* 全局变量: */
/* 调用模块: */
/* 备 注: */
/*-------------------------------------------------------------------*/
bool via_parse_ecm(Smart_Handle_t Handle,U8* pbuf,U8* pucCW)
{
static U8 aucCW[20];
int length;
printf("Viaccess Parse ECM...... Handle = %d\n",Handle);
memset(aucCW,0,20);
length = via_get_cw(Handle,pbuf,aucCW);
printf("get cw length = %d\n",length);
if(length == -2)
{
return false;
}
else if(length > 1)
{
memcpy(pucCW,aucCW+2,16);
return true;
}
return false;
}
/*-------------------------------------------------------------------*/
/* 函 数 名:via_parse_emm */
/* 函数功能:处理EMM数据 */
/* 参 数:pbuf: Emm数据头指针 */
/* 返 回 值: */
/* 全局变量: */
/* 调用模块: */
/* 备 注: */
/*-------------------------------------------------------------------*/
void AnalyseEMMSA(unsigned char *data,int index)
{
memcpy(aucViaEMMBuf8E,&(data[0]),data[2]+3);
}
/*
* function : via_parse_emm
* description : Parse Via EMM to update via smart card
* input : Smart Handle, EMM section , Emm Section Length
* return : true if upate successful , otherwise false
*/
bool via_parse_emm(Smart_Handle_t Handle,U8* data,U16 len)
{
unsigned char cmd[5+188];
unsigned char ucDataBuffer[188];
U8 Response[255];
U8 Status[2];
U16 Read;
if(data[0] == 0x8C || data[0]== 0x8D)
{
memcpy(aucViaEMMBuf8C,data,data[2]+3);
if(aucViaEMMBuf8E[0] == 0x8E)
{
cmd[0] = 0xCA;
cmd[1] = 0xF0;
cmd[2] = 0x00;
cmd[3] = data[7]&0x0F;
cmd[4] = 0x22;
ucDataBuffer[0] = 0x9E;
ucDataBuffer[1] = 0x20;
memcpy(&ucDataBuffer[2],&aucViaEMMBuf8E[7],0x20);
memcpy(cmd+5,ucDataBuffer,0x22);
via_transfer(Handle,cmd,cmd[4]+5,Response,&Read,Status);
if(Status[0]!=0x90)
{
printf("EMM Address Not Matched !!\n");
aucViaEMMBuf8E[0] = 0;
return false;
}
printf("EMM Address Matched !!\n");
cmd[0] = 0xCA;
cmd[1] = 0x18;
cmd[2] = 0x01;
cmd[3] = data[7]&0x0F;/*MK index*/
cmd[4] = data[2]+5;
memcpy(ucDataBuffer,&data[8],data[2]-5);
ucDataBuffer[data[2]-5] = 0xF0;/*fill nano f0 08*/
ucDataBuffer[data[2]-4] = 0x08;
memcpy(&ucDataBuffer[data[2]-3],&aucViaEMMBuf8E[aucViaEMMBuf8E[2]-5],8);
aucViaEMMBuf8E[0] = 0;
memcpy(cmd+5,ucDataBuffer,data[2]+5);
via_transfer(Handle,cmd,cmd[4]+5,Response,&Read,Status);
if(Status[0]==0x91 && Status[1]==0x00) /* 9100 means subscription updated successful */
return true;
}
}
else if(data[0] == 0x8E)
{
AnalyseEMMSA(data,Handle);
if(aucViaEMMBuf8C[0] != 0)
{
cmd[0] = 0xCA;
cmd[1] = 0xF0;
cmd[2] = 0x00;
cmd[3] = aucViaEMMBuf8C[7]&0x0F;
cmd[4] = 0x22;
ucDataBuffer[0] = 0x9E;
ucDataBuffer[1] = 0x20;
memcpy(&ucDataBuffer[2],&data[7],0x20);
memcpy(cmd+5,ucDataBuffer,0x22);
via_transfer(Handle,cmd,cmd[4]+5,Response,&Read,Status);
if(Status[0]!=0x90)
{
aucViaEMMBuf8C[0] = 0;
/*printf("EMM Address Not Matched !! 22\n");*/
return false;
}
/*printf("EMM Address Matched !! 22\n");*/
cmd[0] = 0xCA;
cmd[1] = 0x18;
cmd[2] = 0x01;
cmd[3] = aucViaEMMBuf8C[7]&0x0F;/*MK index*/
cmd[4] = aucViaEMMBuf8C[2]+5;
memcpy(ucDataBuffer,&aucViaEMMBuf8C[8],aucViaEMMBuf8C[2]-5);
ucDataBuffer[aucViaEMMBuf8C[2]-5] = 0xF0;/*fill nano f0 08*/
ucDataBuffer[aucViaEMMBuf8C[2]-4] = 0x08;
memcpy(&ucDataBuffer[aucViaEMMBuf8C[2]-3],&data[data[2]-5],8);
aucViaEMMBuf8C[0] = 0;
memcpy(cmd+5,ucDataBuffer,aucViaEMMBuf8C[2]+5);
via_transfer(Handle,cmd,cmd[4]+5,Response,&Read,Status);
/*printf("Status : %02x %02x 22\n",Status.StatusBlock.T0.PB[0],Status.StatusBlock.T0.PB[1]);*/
if(Status[0]==0x91 && Status[1]==0x00) /* 9100 means subscription updated successful */
return true;
}
}
else if(data[0] == 0x88)
{
cmd[0] = 0xCA;
cmd[1] = 0x18;
cmd[2] = 0x02;
cmd[3] = data[12]&0x0F;
cmd[4] = data[2] - 10;
memcpy(&ucDataBuffer[0], &data[13], data[2] - 10);
memcpy(cmd+5,ucDataBuffer,data[2]-10);
via_transfer(Handle,cmd,cmd[4]+5,Response,&Read,Status);
aucViaEMMBuf8E[0] = 0;
if(Status[0]==0x91 && Status[1] == 0x00) /* 9100 means subscription updated successful */
return true;
}
return false;
}
/*-------------------------------------------------------------------*/
/* 函 数 名:via_transfer */
/* 函数功能:Viaccess数据传输 */
/* 参 数: */
/* 返 回 值: */
/* 全局变量: */
/* 调用模块: */
/* 备 注: */
/*-------------------------------------------------------------------*/
static Smart_ErrorCode_t via_transfer(Smart_Handle_t Handle,
U8* ins,
U16 NumberToWrite,
U8* Response,
U16* Read,
U8* Status)
{
Smart_ErrorCode_t error = SMC_NO_ERROR;
error = Smart_Transfer(Handle,ins,NumberToWrite,Response,0,Read,Status);
return error;
}
/*
* function : via_check_status
* description : check viaccess command procedure bytes
* input : procedure bytes
* return : true if check passed , otherwise false
*/
static bool via_check_status(U8* pb)
{
if(pb[0] == 0x6b)
return false;
else if(pb[0] == 0x6d)
return false;
else if(pb[0] == 0x90)
return true;
else if(pb[0] == 0x91)
return true;
else if(pb[0] == 0x98)
return true;
else
{
printf("Viaccess Check Status failed : %02x %02x\n",pb[0],pb[1]);
return false;
}
}
/////////////////////-------The end --------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -