中国数字电视论坛 注册  |   登录  |   搜索  |  帮助
深圳销售经理(有线传输设备)   深圳售前工程师(HFC/EOC/PON) 珠海DVB-S国内销售 珠海DVB-S海外销售
杭州系统工程师(IPTV)   杭州CATV工程师(IP-QAM)   杭州新闻男主播 杭州电视广告经理 珠海机顶盒技术副总
杭州系统工程师(Linux服务器)   北京广电销售经理(调频发射机)   北京音响工程师(调音台功放)

20万年薪诚聘软件工程师(BOSS)   50万年薪诚聘市场总监(有线电视)   30万年薪诚聘副总经理(机顶盒)   20万年薪诚聘市场经理(手机电视)  
数字电视中文网|DVB中国2009广告招商 中国数字电视人才网|51DTV招聘专业人才猎头解决方案 
中国数字电视论坛  →  网络设备与系统  →  CAS+加扰器与智能卡&破解  →  [转帖]CAS智能卡工作原理和破解关键点C源码示范
共有 3113 人关注过本帖
上一主题 | 下一主题  

[转帖]CAS智能卡工作原理和破解关键点C源码示范

我不在线哦! linhomel 积分:10 等级:新手上路 文章:3 积分:10 注册:2003年6月4日 威望:1 点   楼主 个性首页 QQ 邮箱 主页 发短信 加为好友


#ifndef __sc_def_h__
#define __sc_def_h__

#define U8   unsigned char
#define U16  unsigned short
#define U32  unsigned int
#define bool unsigned char
#define Smart_Handle_t unsigned int
#define Smart_ErrorCode_t  int
#define NULL ((void *)0)
#define SMC_NO_ERROR 0
#define true  1
#define false 0


/*
smart card复位和数据传输的命令各位大虾根据自己的平台自己完成吧,这个应该是小case了!
tf和sm的atr参考:
1. 3b 6c 00 00 4e 54 xx xx xx xx xx xx 4a 03 00 00 (T0?)
2. 3b 02 02 80 (也是T0? 嘿嘿!)

*/
Smart_ErrorCode_t Smart_Reset(Smart_Handle_t Handle,U8* pucAtrBuffer,
         U8* pucAtrLength,U8* pucHistoryLength);//智能卡复位

Smart_ErrorCode_t Smart_Transfer(Smart_Handle_t Handle,U8* pucCommand,
         U16 uNumberToWrite, U8* pucResponse,
         U16 uNumberToRead,U16* pusNumberRead,
         U8* pucPBWords);//智能卡数据传输

#endif /* __sc_def_h__ */

 

/******************************************************
 * 文件名:smsx.c
 * 功  能:处理SCA命令
 * 作  者:
 * 日  期:
 *****************************************************/

#include <stdio.h>
#include <memory.h>
#include "smsx.h"


Smsx_Info_t  smsx;
Smsx_Info_t* pstSmsxInfo;

static Smart_ErrorCode_t smsx_transfer(
           Smart_Handle_t Handle,
           U8*     ins,
           U16     NumberToWrite,
           U8*     Response,
           U16*     Read,
           U8*            Status);//数据传输
bool smsx_readdata(Smart_Handle_t Handle,U8 len,U8 *outbuf);
static bool smsx_begincmd(Smart_Handle_t Handle);
static bool smsx_get_sn(Smart_Handle_t Handle);//读取智能卡号码

/************************************************************************/
/* 初始化, 主要工作是读取卡内的基本信息,如卡号、运营商等信息
  
   输入     handle -- smart card 句柄
   输出     无
   返回值   true -- 初始化成功 false -- 初始化失败
   其他                                                                 */
/************************************************************************/
bool smsx_init(Smart_Handle_t handle)
{
 pstSmsxInfo = &smsx;
 memset(pstSmsxInfo,0,sizeof(Smsx_Info_t));

 if(!smsx_begincmd(handle))
 {
  printf("smsx init : begin cmd failed !!\n");
//  return false;
 }

 if(!smsx_get_sn(handle))
 {
  printf("smsx init : get sn failed !!\n");
//  return false;
 }

 printf("SMSX Init OK !!\n");

 return true;
}


/************************************************************************/
/* 起始指令,  这个命令在智能卡 Reset 后必须首先执行,之后才可以执行其他的命令

   输入     Handle -- smart card 句柄
   输出     无
   返回值   true -- 命令执行成功 false -- 命令执行失败
   其他                                   

通讯示例:

00 A4 04 00 02 A4 3F 00
90 00
00 A4 04 00 02 A4 4A 00
90 00
                                                                       */
/************************************************************************/
static bool smsx_begincmd(Smart_Handle_t Handle)
{
 U8 cmd[16]={0x00,0xa4,0x04,0x00,0x02,0x3F,0x00};
 U8 response[10];
 U8 pbword[2]={0};
 U16 cmdlen=0;
 U16 replen=0;
 Smart_ErrorCode_t bresult=SMC_NO_ERROR;
 
 cmd[5] = 0x3F;
 cmd[6] = 0x00;
 cmdlen=cmd[4]+5;
 bresult=smsx_transfer(Handle,cmd,cmdlen,response,&replen,pbword);

// if(bresult!=SMC_NO_ERROR)
// {
//  return false;
// }

 if((pbword[0]!=0x90)||(pbword[1]!=0x00))
 {
  return false;
 }


 cmd[5] = 0x4A;
 cmd[6] = 0x00;
 cmdlen=cmd[4]+5;
    bresult=smsx_transfer(Handle,cmd,cmdlen,response,&replen,pbword);

// if(bresult!=SMC_NO_ERROR)
// {
//  return false;
// }

 if((pbword[0]!=0x90)||(pbword[1]!=0x00))
 {
  return false;
 }

 return true;
}


/************************************************************************/
/* 读取智能卡号码和智能卡ID,卡号是授权需要用到的,ID就是卡片上显示的一串数字了

   输入     Handle -- smart card 句柄
   输出     无
   返回值   true -- 获取卡号成功 false -- 获取卡号失败
   其他     得到的卡号存储于全局变量pstYxtfInfo中,可用于OSD显示                              

通讯示例:


00 B2 00 05 06 B2 00 01 FF 00 01 FF
61 67
00 C0 00 00 67 C0
00 00 00 xx xx xx xx yy yy yy yy yy yy yy yy 00 //卡号 xx xx xx xx (十六进制) ID yy yy yy yy yy yy yy yy(字符串)
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 90 00                        */
/************************************************************************/
bool smsx_get_sn(Smart_Handle_t Handle)
{
 U8 cmd[]={0x00,0xB2,0x00,0x05,0x06,0x00,0x01,0xFF,0x00,0x01,0xFF};
 U8 response[200];
 U8 pbword[2]={0};
 U16 cmdlen=0;
 U16 replen=0;
 Smart_ErrorCode_t bresult=SMC_NO_ERROR;

 U8 nextreadsize=0;
 
 cmdlen = 5+cmd[4];

 bresult=smsx_transfer(Handle,cmd,cmdlen,response,&replen,pbword);

// if(bresult!=SMC_NO_ERROR)
// {
//  return false;
// }

 if((pbword[0]&0xf0)!=0x60)
 {
  return false;
 }
 nextreadsize=pbword[1];
 
 if(smsx_readdata(Handle,nextreadsize,response)!=true)
 {
  return false;
 }

 memcpy(pstSmsxInfo->uCardUA, response+7, 8);//卡片上显示的一串号码
    pstSmsxInfo->uCardNumber=(response[3]<<24)+(response[4]<<16)+(response[5]<<8)+response[6];//这才是授权用的号码!
 return true;
}

/************************************************************************/
/* 处理解析ECM,得到CW,呵呵,得到它我们就可以看节目了!收取ECM的时候设置filter
的第一个字节0x80/0x81就ok了

   输入     Handle -- smart card 句柄  buf -- ECM信息,从0x80/0x81开始
   输出     pucCW  -- 就是cw啦,16个字节,不是奇偶,就是奇偶,根据情况你自己试验
   返回值   true -- 解析ECM成功 false --解析ECM失败
   其他      
                                                                        */
/************************************************************************/

bool smsx_parse_ecm(Smart_Handle_t Handle,U8* buf,U8* pucCW)
{
 U8  cmd1[200]={0x80,0x32,0x00,0x00,0x3C};
 U8  cmd2[10]={0x00,0xc0,0x00,0x00};
 U8 reponse[100];
 U16 writelen = 0;
 U16 replen=0;
 U8  status[2];
 U8* pbuf = buf;
 int i = 0;

 writelen = pbuf[2]+3+5;
// printf("ecm write len = %d\n", writelen);
 cmd1[4] = pbuf[2]+3;
 memcpy(cmd1+5,pbuf,writelen-5);//要对ECM数据加个命令头再传给智能卡
 smsx_transfer(Handle,cmd1,writelen,reponse,&replen,status);

 if (replen >= 2)
 {
  cmd2[4] = reponse[1];
 }
 else
 {
  if((status[0]&0xf0)==0x60)
  {
   cmd2[4] = status[1];
  }
  else
  {
   return false;
  } 
 }
 
 smsx_transfer(Handle,cmd2,5,reponse,&replen,status);

// printf("rsp len = %d\n", replen);
 if (replen > 32)  //这个地方很有意思,如果不这样处理一下,一个字节之差,节目也放不出来
 {
  if(buf[0]==0x80)
  {
   memcpy(pucCW, reponse+18,4);
   memcpy(pucCW+4, reponse+18+4+1,4);
   memcpy(pucCW+8, reponse+18+8+1,4);
   memcpy(pucCW+12, reponse+18+8+1+4+1,4);
  }
  else
  {
   memcpy(pucCW, reponse+18+8+1,4);
   memcpy(pucCW+4, reponse+18+8+1+4+1,4);
    memcpy(pucCW+8,reponse+18,4);
   memcpy(pucCW+12,reponse+18+4+1,4);
  }
 }
 else
 {
  return false;
 }

 return true;
}

/************************************************************************/
/* 处理EMM,主要就是完成对卡授权了。收取EMM的时候设置filter的第一个字节0x82,
5,6,7,8个字节就是卡号了,注意不是ID啊。可以仅设置第一个字节,多收几个EMM
研究研究哦!

   输入     Handle -- smart card 句柄  data -- EMM信息,len -- 数据长度
   输出     无
   返回值   true -- 解析EMM成功 false --解析EMM失败
   其他                                                                   */
/************************************************************************/

bool smsx_parse_emm(Smart_Handle_t Handle,U8* buf,U16 len)
{
 U8  cmd1[100]={0x80,0x30,0x00,0x00,0x4C};
 U8  cmd2[10]={0x00,0xc0,0x00,0x00};
 U8 reponse[100];
 U16 writelen = 0;
 U16 replen=0;
 U8  status[2];

 writelen = buf[2]+3+5;
 cmd1[4] = buf[2]+3;
 memcpy(cmd1+5,buf,writelen-5);//要对EMM数据加个命令头再传给智能卡
 smsx_transfer(Handle,cmd1,writelen,reponse,&replen,status);
 
 
 if (replen > 2)
 {
  return true;
 
 }else
 {
  return false;
 }

 return true;
}
/************************************************************************/
/* 数据传输,机顶盒和智能卡通讯的接口

   输入     Handle -- smart card 句柄,ins -- 要传送的数据,NumberToWrite --
 要传送的数据长度
   输出     Response -- 回应数据, Read -- 回应的数据长度,Status -- 状态字节
   返回值   数据传输错误类型 SMC_NO_ERROR表示无错误
   其他           
                                                                        */
/************************************************************************/
static Smart_ErrorCode_t smsx_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);

// printf("Status[0]=0x%02x  Status[1]=0x%02x error = %d\n",Status[0],Status[1],error);
 return error;
}

/************************************************************************/
/*从卡中读取指定长度的数据

   输入     Handle -- smart card 句柄,len -- 要从智能卡中读取的数据长度
   输出     outbuf -- 智能卡回应的数据
   返回值   true -- 读取数据成功 false -- 读取数据失败
   其他                                                                 */
/************************************************************************/
bool smsx_readdata(Smart_Handle_t Handle,U8 len,U8 *outbuf)
{
 U8  cmd[]={0x00,0xc0,0x00,0x00,0xff};
 U8  reponse[255];
 U16  cmdlen=5;
 U16  replen=0;
 U8  pbword[2]={0};
 Smart_ErrorCode_t bresult=SMC_NO_ERROR;

 memset(reponse,0,255);
 cmd[4] = len;
 bresult=smsx_transfer(Handle,cmd,cmdlen,reponse,&replen,pbword);

// if(bresult!=SMC_NO_ERROR)
// {
//  return false;
// }

 if((pbword[0]==0x90)&&(pbword[1]==0x00)&&(replen==len))
 {
  memcpy(outbuf,reponse,replen);
  return true;
 }
 else
 {
  return false;
 }
}///////////---The end---------



[该帖子由作者于2008年9月10日 14:04:07最后编辑]
广州诚毅BOSS · 广播电视综合业务运营支撑系统
2008-9-10 14:00:49   举报   Top
我不在线哦! linhomel 积分:10 等级:新手上路 文章:3 积分:10 注册:2003年6月4日 威望:1 点   沙发 个性首页 QQ 邮箱 主页 发短信 加为好友

/******************************************************
 * 文件名:yxtf.c
 * 功  能:处理TCA命令
 * 作  者:
 * 日  期:
 *****************************************************/

#include <stdio.h>
#include "memory.h"
#include "yxtf.h"

Yxtf_Info_t  yxtf;
Yxtf_Info_t* pstYxtfInfo = NULL;

static Smart_ErrorCode_t yxtf_transfer(Smart_Handle_t Handle,
           U8*       ins,
           U16       NumberToWrite,
           U8*       Response,
           U16*       Read,
           U8* Status);//数据传输
static bool yxtf_readdata(Smart_Handle_t Handle,U8 len,U8 *outbuf);
static bool yxtf_begincmd(Smart_Handle_t Handle);
static bool yxtf_get_sn(Smart_Handle_t Handle);//读取智能卡号码
static bool yxtf_get_prov(Smart_Handle_t Handle);//获取运营商信息
static bool yxtf_check_pairing(Smart_Handle_t Handle);//检查机卡配对


/************************************************************************/
/* 初始化, 主要工作是读取卡内的基本信息,如卡号、运营商等信息
  
   输入     handle -- smart card 句柄
   输出     无
   返回值   true -- 初始化成功 false -- 初始化失败
   其他                                                                 */
/************************************************************************/
bool yxtf_init(Smart_Handle_t handle)
{
 pstYxtfInfo = &yxtf;
 memset(pstYxtfInfo,0,sizeof(Yxtf_Info_t));

 if(!yxtf_begincmd(handle))
 {
//  return false;
 }

#if 0
 if(!yxtf_get_prov(handle))
 {
  printf("yxtf init : get prog info failed !!\n");
  return false;
 }
#endif

 if(!yxtf_get_sn(handle))
 {
  printf("yxtf init : get sn failed !!\n");
//  return false;
 }
 
 if(!yxtf_check_pairing(handle))
 {
  printf("yxtf init : get sn failed !!\n");
//  return false;
 }
 
 printf("yxtf Init OK !!\n");
 return true;
}

/************************************************************************/
/* 起始指令,  这个命令在智能卡 Reset 后必须首先执行,之后才可以执行其他的命令

   输入     Handle -- smart card 句柄
   输出     无
   返回值   true -- 命令执行成功 false -- 命令执行失败
   其他                                   

通讯示例:
00 A4 04 00 05 A4 F9 5A 54 00 06
90 00
                                                                       */
/************************************************************************/
static bool yxtf_begincmd(Smart_Handle_t Handle)
{
 U8 cmd[]={0x00,0xa4,0x04,0x00,0x05,0xf9,0x5a,0x54,0x00,0x06};
 U8 response[10];
 U8 pbword[2]={0};
 U16 cmdlen=0;
 U16 replen=0;
 Smart_ErrorCode_t bresult=SMC_NO_ERROR;
 
 cmdlen=10;
 bresult=yxtf_transfer(Handle,cmd,cmdlen,response,&replen,pbword);

// if(bresult!=SMC_NO_ERROR)
// {
//  return false;
// }

 if((pbword[0]!=0x90)||(pbword[1]!=0x00))
 {
  return false;
 }
 return true;
}

/************************************************************************/
/* 读取运营商ID列表

   输入     Handle -- smart card 句柄
   输出     无
   返回值   true -- 获取运营商信息成功 false -- 获取运营商信息失败
   其他     得到的运营商信息存储于全局变量pstYxtfInfo中,可用于OSD显示                              

通讯示例:

80 44 00 00 08 44
xx xx 00 00 xx xx 00 00 90 00 //每两个字节就是一个运营商的ID?   */
/************************************************************************/

static bool yxtf_get_prov(Smart_Handle_t Handle)
{
 U8 cmd[5]={0x80,0x44,0x00,0x00,0x08};
 U8 response[10];
 U8 pbword[2]={0};
 int cmdlen=0;
 U16 replen=0;
 Smart_ErrorCode_t bresult=SMC_NO_ERROR;

 int provcount=0;
 int i;

 cmdlen = 5+cmd[4];
 bresult = yxtf_transfer(Handle,cmd,cmdlen,response,&replen,pbword);
// if(bresult!=SMC_NO_ERROR)
// {
//  return false;
// }
 /*首先检查过程字节是否正确*/
 if((pbword[0]!=0x90)||(pbword[1]!=0x00))
 {
  return false;
 }
 
 for(i=0;i<MAX_PROV_COUNT;i++)//好像是最多支持4个
 {
  if((response[i*2]!=0)||(response[i*2+1]!=0))
  {
   provcount++;
   pstYxtfInfo->provID=(response[i*2]<<8)|response[i*2+1];
   printf("the provid[%d] =0x%04x\n",i,pstYxtfInfo->provID);
  }
 }
}


/************************************************************************/
/* 读取智能卡号,就是tf卡片上显示的第三组数字,tf也拿来用做授权寻址

   输入     Handle -- smart card 句柄
   输出     无
   返回值   true -- 获取卡号成功 false -- 获取卡号失败
   其他     得到的卡号存储于全局变量pstYxtfInfo中,可用于OSD显示                              

通讯示例:


80 46 00 00 04 46 01 00 00 04
61 04
00 C0 00 00 04 C0
xx xx xx xx 90 00   //卡号 xx xx xx xx (十六进制)                     */
/************************************************************************/
bool yxtf_get_sn(Smart_Handle_t Handle)
{
 U8 cmd[]={0x80,0x46,0x00,0x00,0x04,0x01,0x00,0x00,0x04};
 U8 response[100];
 U8 pbword[2]={0};
 U16 cmdlen=0;
 U16 replen=0;
 Smart_ErrorCode_t bresult=SMC_NO_ERROR;

 U8 nextreadsize=0;
 
 cmdlen = 5+cmd[4];

 bresult=yxtf_transfer(Handle,cmd,cmdlen,response,&replen,pbword);

// if(bresult!=SMC_NO_ERROR)
// {
//  return false;
// }

 if((pbword[0]&0xf0)!=0x60)
 {
  return false;
 }
 nextreadsize=pbword[1];
 
 if(yxtf_readdata(Handle,nextreadsize,response)!=true)
 {
  return false;
 }

 pstYxtfInfo->uCardNumber=(response[0]<<24)+(response[1]<<16)\
         +(response[2]<<8)+response[3];//卡号,卡片上显示的第三组数字,也是授权用的号码
 return true;
}


/************************************************************************/
/* 检查机卡配对

   输入     Handle -- smart card 句柄
   输出     无
   返回值   true -- 检查机卡配对成功 false -- 检查机卡配对失败
   其他     得到的机卡配对状态存储于全局变量pstYxtfInfo中,可用于OSD显示                              

通讯示例:
 
80 4C 00 00 04 4C FF FF FF FF
94 B1     -- 该卡没有和任何机顶盒绑定
    或者
94 B2     -- 该卡已经和机顶盒绑定(不一定是当前机顶盒哦!)                                                                   */
/************************************************************************/

static bool yxtf_check_pairing(Smart_Handle_t Handle)
{
 U8   cmd1[200]= {0x80,0x4c,0x00,0x00,0x04,0xFF,0xFF,0xFF,0xFF};
 U8  reponse[100];
 U16  writelen = 0;
 U16  replen=0;
 U8   status[2];
 int  i = 0;
 
 writelen = cmd1[4]+5;
 yxtf_transfer(Handle,cmd1,writelen,reponse,&replen,status);
 
 if ((status[0] == 0x94)&&(status[1] == 0xB1) )
 {
  printf("该卡没有和任何机顶盒绑定!\n");

  pstYxtfInfo->paringflag = 0;
  return true;
 }
 else if ((status[0] == 0x94)&&(status[1] == 0xB2) )
 {
  pstYxtfInfo->paringflag = 1;
 
        printf("该卡已经和机顶盒绑定!\n");

  return true;
 }
 else
 {
  pstYxtfInfo->paringflag = 2;
  return false;
 }
}

 


上海高清奇普 · DMB-TH机顶盒 · HDMI分配器 · ASI高清码流仪
2008-9-10 14:01:39   举报   Top
我不在线哦! linhomel 积分:10 等级:新手上路 文章:3 积分:10 注册:2003年6月4日 威望:1 点   板凳 个性首页 QQ 邮箱 主页 发短信 加为好友

 

 
/************************************************************************/
/* 机卡配对,一般情况没必要用的,在有些地方,tf在ECM中设置了要求智能卡配对
才能解出cw,这个时候想办法得到配对信息,执行下面这个命令,就可以完成智能卡和
你的机顶盒配对了。那些以为机卡配对了就无法共享的想法应该是天真的,至少对tf
来说是这样。

   输入     Handle -- smart card 句柄 pairingcode -- 4字节的配对信息,卡和
对应的机器通讯过程中有,对应的机器flash中也存有一个,紧挨着卡号的信息
   输出     无
   返回值   true -- 机卡配对成功 false -- 机卡配对失败
   其他      

80 4C 00 00 04 4C xx xx xx xx
90 00      //当前机卡配对
   或者
94 B2(?)   //没仔细研究具体是什么,卡和其它机顶盒绑定                    */
/************************************************************************/

bool yxtf_pairing(Smart_Handle_t Handle, U8* pairingcode)// pairingcode 4字节的配对信息,
{
 U8  cmd1[200]= {0x80,0x4c,0x00,0x00,0x04,0xFF,0xFF,0xFF,0xFF};
 U8 reponse[100];
 U16 writelen = 0;
 U16 replen=0;
 U8  status[2];
 int i = 0;
 
 memcpy(cmd1+5, pairingcode, 4);

 writelen = cmd1[4]+5;
 yxtf_transfer(Handle,cmd1,writelen,reponse,&replen,status);

 if((status[0]==0x90)||(status[1]==0x00))
 {
    printf("当前机卡绑定!\n");
 }
 else
 {
 // printf("************Status[0]=%02x Status[1]=%02x*********\n",status[0],status[1]);
  printf("该卡已绑定其它机顶盒!\n");

  return false;
 }
 
 return true;

}

/************************************************************************/
/* 处理解析ECM,得到CW,呵呵,得到它我们就可以看节目了!收取ECM的时候设置filter
的第一个字节0x80/0x81就ok了

   输入     Handle -- smart card 句柄  buf -- ECM信息,从0x80/0x81开始
   输出     pucCW  -- 就是cw啦,16个字节,不是奇偶,就是奇偶,根据情况你自己试验
   返回值   true -- 解析ECM成功 false --解析ECM失败
   其他      
                                                                        */
/************************************************************************/

bool yxtf_parse_ecm(Smart_Handle_t Handle,U8* buf,U8* pucCW)
{
 U8  cmd1[200]={0x80,0x3a,0x00,0x01,0x53};
 U8  cmd2[10]={0x00,0xc0,0x00,0x00};
 U8 reponse[100];
 U16 writelen = 0;
 U16 replen=0;
 U8  status[2];
 U8* pbuf = buf;
 int i = 0;

 for (i=0; i<(buf[2]+3); i++)//找到真正要往卡里送的数据
 {
  if ((pbuf[0]==0x80)&&(pbuf[1]==0x3a))
  {
   break;
  }
  else
  {
   pbuf = buf+i+1;
  }
 }

 writelen = pbuf[4]+5;
// printf("ecm write len = %d\n", writelen);
 memcpy(cmd1,pbuf,writelen);
 yxtf_transfer(Handle,cmd1,writelen,reponse,&replen,status);

 if (replen >= 2)
 {
  cmd2[4] = reponse[1];
 }
 else
 {
  if((status[0]&0xf0)==0x60)
  {
   cmd2[4] = status[1];
  }
  else
  {
   return false;
  } 
 }
 
 yxtf_transfer(Handle,cmd2,5,reponse,&replen,status);

 //printf("rsp len = %d\n", replen);
 if (replen > 23) 
 {//很怀疑tf的做法,但是他们就是这么做的,很明显没有加密啊,hoho~ ~
  if(buf[0]==0x80)
   memcpy(pucCW, reponse+8,16);
  else
  {
   memcpy(pucCW, reponse+16,8);
    memcpy(pucCW+8,reponse+8,8);
  }
 }
 else
 {
  return false;
 }

 return true;
}

/************************************************************************/
/* 处理EMM,主要就是完成对卡授权了。收取EMM的时候设置filter的第一个字节0x82,
5,6,7,8个字节就是卡号了。可以仅设置第一个字节,多收几个EMM研究研究哦!

   输入     Handle -- smart card 句柄  data -- EMM信息,len -- 数据长度
   输出     无
   返回值   true -- 解析EMM成功 false --解析EMM失败
   其他                                                                   */
/************************************************************************/

bool yxtf_parse_emm(Smart_Handle_t Handle,U8* data,U16 len)
{
 U8  cmd1[100]={0};
 U8  cmd2[10]={0x00,0xc0,0x00,0x00};
 U8 reponse[100];
 U16 writelen = 0;
 U16 replen=0;
 U8  status[2];

 writelen = data[15]+5;
 memcpy(cmd1,data+11,writelen);//找到真正要往卡里送的数据
 yxtf_transfer(Handle,cmd1,writelen,reponse,&replen,status);
 
 if (replen > 2)
 {
  return true;
 
 }else
 {
  return false;
 }

 return true;
}

/************************************************************************/
/* 数据传输,机顶盒和智能卡通讯的接口

   输入     Handle -- smart card 句柄,ins -- 要传送的数据,NumberToWrite --
 要传送的数据长度
   输出     Response -- 回应数据, Read -- 回应的数据长度,Status -- 状态字节
   返回值   数据传输错误类型 SMC_NO_ERROR表示无错误
   其他           
                                                                        */
/************************************************************************/
static Smart_ErrorCode_t yxtf_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);
// printf("Status[0]=0x%02x  Status[1]=0x%02x error = %d\n",Status[0],Status[1],error);
 return error;
}

/************************************************************************/
/*从卡中读取指定长度的数据

   输入     Handle -- smart card 句柄,len -- 要从智能卡中读取的数据长度
   输出     outbuf -- 智能卡回应的数据
   返回值   true -- 读取数据成功 false -- 读取数据失败
   其他                                                                 */
/************************************************************************/
static bool yxtf_readdata(Smart_Handle_t Handle,U8 len,U8 *outbuf)
{
 U8  cmd[]={0x00,0xc0,0x00,0x00,0xff};
 U8  reponse[255];
 U16  cmdlen=5;
 U16  replen=0;
 U8  pbword[2]={0};
 Smart_ErrorCode_t bresult=SMC_NO_ERROR;

 memset(reponse,0,255);
 cmd[4] = len;
 bresult=yxtf_transfer(Handle,cmd,cmdlen,reponse,&replen,pbword);

// if(bresult!=SMC_NO_ERROR)
// {
//  return false;
// }

 if((pbword[0]==0x90)&&(pbword[1]==0x00)&&(replen==len))
 {
  memcpy(outbuf,reponse,replen);
  return true;
 }
 else
 {
  return false;
 }
}


///////////---The end---------

 
/*
本代码仅作为学习研究的目的使用,请您于24小时内自觉将其删除,请勿应用于商业活动或其它赢利性活动中,
否则后果自负!
*/

/******************************************************
 * 文件名:smsx.h
 * 功  能:处理SCA命令
 * 作  者:
 * 日  期:
 *****************************************************/

#ifndef _smsx_h_
#define _smsx_h_

#include "sc_def.h"

typedef struct 
{
 U32      uCardNumber;//智能卡号
    U8         uCardUA[9];//智能卡ID,就是卡片上面显示的一串数
 U8      iAgeGrade; //年龄等级

}Smsx_Info_t;


bool smsx_init(Smart_Handle_t handle); //初始化,主要工作是读取卡内的基本信息,如卡号、运营商等信息
bool smsx_parse_ecm(Smart_Handle_t Handle,U8* pbuf,U8* pucCW);//解析ECM,得到CW
bool smsx_parse_emm(Smart_Handle_t Handle,U8* pbuf,U16 len);//解析EMM,完成授权等

#endif /* _smsx_h_ */
 


上海高清奇普 · DMB-TH机顶盒 · HDMI分配器 · ASI高清码流仪
2008-9-10 14:01:48   举报   Top
我正在线哦! 左脚踩右脚,一蹦三丈高 积分:24 等级:新手上路 文章:14 积分:24 注册:2008年5月14日 威望:0 点   木地板 个性首页 QQ 邮箱 主页 发短信 加为好友
俺白勺女良口艾~~
上海高清奇普 · DMB-TH机顶盒 · HDMI分配器 · ASI高清码流仪
2008-9-10 14:30:33   举报   Top
我不在线哦! cnfeihong 积分:386 等级:业余侠客 文章:60 积分:386 注册:2005年10月15日 威望:1 点   第 5 楼 个性首页 QQ 邮箱 主页 发短信 加为好友
拜托,来点儿有技术含量的好不好,编译都通不过还好意思贴出来?
上海高清奇普 · DMB-TH机顶盒 · HDMI分配器 · ASI高清码流仪
2008-9-10 15:15:02   举报   Top
我不在线哦! 塔尔诺夫斯基 积分:84 等级:新手上路 文章:71 积分:84 注册:2008年4月28日 威望:3 点   第 6 楼 个性首页 QQ 邮箱 主页 发短信 加为好友

晕!刚试过可以通啊!

就是没看懂!

你一个文件一个文件的来!

不用谢了!呵呵

广州易迩达Tuner · DVB-S2 · DMB-TH · Car Tuner · DVB-T · DVB-S
2008-9-10 17:56:12   举报   Top
我正在线哦! jzheng 积分:36 等级:新手上路 文章:6 积分:36 注册:2006年8月18日 威望:0 点   第 7 楼 个性首页 QQ 邮箱 主页 发短信 加为好友

这段东西怎么用法啊,楼主不能光发了帖子,没个使用说明啊,如何知道是真的假的啊??

[em145][em145]
广州易迩达Tuner · DVB-S2 · DMB-TH · Car Tuner · DVB-T · DVB-S
2008-9-10 19:26:42   举报   Top
我正在线哦! xiaofeixia 积分:90 等级:新手上路 文章:18 积分:90 注册:2007年3月26日 威望:0 点   第 8 楼 个性首页 QQ 邮箱 主页 发短信 加为好友
最近奥运开完了,好像各地招标也热闹起来了,这样的帖子也就多了,不难理解啊,竞争嘛要靠点手段的。僧是越来越多,粥是越来越少啊,现在业界的兄弟们都不好过啊。不过我还是觉得大家应该坐下来踏踏实实做事情。。。。。
广州易迩达Tuner · DVB-S2 · DMB-TH · Car Tuner · DVB-T · DVB-S
2008-9-10 21:04:43   举报   Top
我不在线哦! happypaay 积分:26 等级:新手上路 文章:14 积分:26 注册:2008年8月18日 威望:2 点   第 9 楼 个性首页 QQ 邮箱 主页 发短信 加为好友

不知道要在哪个平台上编译

广州易迩达Tuner · DVB-S2 · DMB-TH · Car Tuner · DVB-T · DVB-S
2008-9-11 10:08:20   举报   Top
我不在线哦! happypaay 积分:26 等级:新手上路 文章:14 积分:26 注册:2008年8月18日 威望:2 点   第 10 楼 个性首页 QQ 邮箱 主页 发短信 加为好友

貌似有几个函数的原型没有给出来哦

只是给了接口

广州易迩达Tuner · DVB-S2 · DMB-TH · Car Tuner · DVB-T · DVB-S
2008-9-11 10:53:34   举报   Top
1234  34 | 10    1/4 页

北京DRM系统工程师(PKI/CA)    杭州有线电视市场副总裁(互动电视)      珠海机顶盒副总经理(ST高清)      北京BOSS软件工程师(Ruby/J2EE)