📄 conax.c
字号:
/*
本代码仅作为学习研究之目的使用,请您于24小时内自觉将其删除,请勿应用于商业活动或其它赢利性活动中,
否则后果自负!
*/
/******************************************************
* 文件名:conax.c
* 功 能:处理CCA命令
* 作 者:
* 日 期:
*****************************************************/
#include "conax.h"
Conax_Info_t* pstConaxInfo = NULL;
/* TAG 定义 */
#define ASCII_TXT_TAG 0x01
#define OCTET_TAG 0x20
#define TIME_TAG 0x30
#define PRODUCT_ID_TAG 0x46
#define PRICE_TAG 0x47
#define EMM_ADDRESS_TAG 0x23
/* 命令参数PI */
#define CASS_VER_PI 0x20
#define CA_SYS_ID_PI 0x28
#define COUNTRY_INDICATOR_PI 0x2F
#define MAT_RAT_LEVEL_PI 0x30
#define SESSION_INFO_PI 0x23
#define CA_DESC_EMM_PI 0x22
#define HOST_DATA_PI 0x80
#define ACCESS_STATUS_PI 0x31
#define CW_PI 0x25
#define CARD_NUMBER_PI 0x74
typedef struct
{
U16 cw_id; /* CW ID (not used) */
U8 odd_even_indicator; /* ODD EVEN Indicator */
U8 aucCWBuf[8]; /* CW buf */
U8 iCWLen; /* CW length */
}Conax_CW_t; /* CW参数 */
typedef struct
{
unsigned not_sufficient_info : 1;
unsigned access_granted : 1;
unsigned order_ppv_event : 1;
unsigned geographical_blackout : 1;
unsigned maturity_rating : 1;
unsigned accept_viewing : 1;
unsigned ppv_preview : 1;
unsigned ppv_expried : 1;
unsigned no_access_to_network : 1;
U8 current_mat_rat_value;
U16 minutes_left;
U8 product_ref[6];
}Conax_AccessStatus_t; /* Conax接收状态参数(PI=0x31) */
static Smart_ErrorCode_t ConaxRead(Smart_Handle_t Handle,
U8* Buffer,
U16 NumberToRead,
U16* Read,
U8* Status,
U8 SID);
static bool ConaxInitCASS(Smart_Handle_t Handle);
static bool ConaxResetSESS(Smart_Handle_t Handle, U8 sid);
static bool ConaxParseResp(Smart_Handle_t Handle,U8* Response,U16 len);
static bool ConaxParseCADescEMM(Smart_Handle_t Handle,U8* pBuf);
static bool ConaxParseAccessStatus(Smart_Handle_t Handle,U8* Response);
static bool ConaxReqCardNumber(Smart_Handle_t Handle);
static bool ConaxCAStatusSelect(Smart_Handle_t Handle,
U8 type,
U8* buf);
/*-------------------------------------------------------------------*/
/* 函 数 名:conax_init(Smart_Handle_t Handle) */
/* 函数功能:Conax CA初始化函数 */
/* 参 数: */
/* 返 回 值: */
/* 全局变量: */
/* 调用模块: */
/* 备 注: */
/*-------------------------------------------------------------------*/
bool conax_init(Smart_Handle_t Handle)
{
pstConaxInfo = &conax;
memset(pstConaxInfo,0,sizeof(Conax_Info_t));
if(!ConaxInitCASS(Handle))
{
printf("Conax Init : Init CASS failed !!\n");
return false;
}
if(!ConaxResetSESS(Handle,0))
{
printf("Conax Init : Reset SESS failed !!\n");
return false;
}
if(!ConaxCAStatusSelect(Handle,0x00,NULL))
{
printf("Conax Init : Select Status 0 failed !!\n");
return false;
}
if(!ConaxCAStatusSelect(Handle,0x01,NULL))
{
printf("Conax Init : Select Status 1 failed !!\n");
return false;
}
if(!ConaxReqCardNumber(Handle))
{
printf("Conax Init : Read Card Number failed !!\n");
return false;
}
printf("Conax CA init OK!!!!!!!!!!!!\n");
return true;
}
/*-------------------------------------------------------------------*/
/* 函 数 名:ConaxRead */
/* 函数功能:Conax CA初始化函数 */
/* 参 数:Handle: SmartCard句柄 */
/* NumberToRead: 要读的字节个数 */
/* Buffer: 存放所读取数据的缓冲区 */
/* Read: 实际读取的数据个数 */
/* Status: 操作状态 */
/* SID: 会话号 */
/* 返 回 值: */
/* 全局变量: */
/* 调用模块: */
/* 备 注: */
/*-------------------------------------------------------------------*/
static Smart_ErrorCode_t ConaxRead(Smart_Handle_t Handle,
U8* Buffer,
U16 NumberToRead,
U16* Read,
U8* Status,
U8 SID)
{
U8 ins[] = {0xDD,0xCA,0x00,0xFF,0xFF}; /* ISO part of Read Command */
Smart_ErrorCode_t error;
ins[3] = SID; /* Set session ID */
ins[4] = (U8)NumberToRead; /* Set param of the read command */
error = Smart_Transfer(Handle, /* Send the command to the card */
ins,
5,
Buffer,
0,
Read,
Status);
return error;
}
/*-------------------------------------------------------------------*/
/* 函 数 名:ConaxWrite */
/* 函数功能:Conax CA发送命令函数 */
/* 参 数:Handle: SmartCard句柄 */
/* Buffer: 要发送的命令 */
/* NumberToWrite: 命令长度 */
/* 返 回 值: */
/* 全局变量: */
/* 调用模块: */
/* 备 注: */
/*-------------------------------------------------------------------*/
static bool ConaxWrite(Smart_Handle_t Handle,
U8* Buffer,
U16 NumberToWrite)
{
Smart_ErrorCode_t error;
U8 Status[2];
U8 Response[255];
U16 Read;
bool tmpresult;
error = Smart_Transfer(Handle,
Buffer,
NumberToWrite,
Response,
0,
&Read,
Status);
if(error == SMC_NO_ERROR)
{
/* We must do different things according to different Procedure bytes */
switch(Status[0])
{
case 0x90:
switch(Status[1])
{
case 0x00:
tmpresult = true;
break;
default:
tmpresult = false;
break;
}
break;
case 0x98:
/* We must read the data provide by the card */
error = ConaxRead(Handle,
Response,
Status[1],
&Read,
Status,
0);
/* We have to know what data we have got */
if(error == SMC_NO_ERROR)
{
if(ConaxParseResp(Handle,Response,Read))
tmpresult = false;
else
{
printf("Conax Parse Response Failed !!\n");
tmpresult = false;
}
}
else
{
tmpresult = false;
}
break;
default:
tmpresult = false;
break;
}
}
return tmpresult;
}
/*-------------------------------------------------------------------*/
/* 函 数 名:ConaxParseResp */
/* 函数功能:分析Conax卡的响应数据 */
/* 参 数:Response: 响应数据头指针 */
/* len: 响应数据长度 */
/* 返 回 值:成功:true */
/* 失败:false */
/* 全局变量: */
/* 调用模块: */
/* 备 注: */
/*-------------------------------------------------------------------*/
static bool ConaxParseResp(Smart_Handle_t Handle,U8* Response,U16 len)
{
U8* buf;
U8 pi;
int iLength = 0;
U16 iTmpLen = 0;
U16 iOctLen = 0;
int iParsedLength = 0;
Conax_CW_t ConaxCW;
buf = Response;
while(iParsedLength < len)
{
pi = buf[0];
iLength = buf[1];
/* Each data have a pi parameter,we use this to identify them */
switch(pi)
{
/* The following five objects can be received after INIT_CASS command */
case CASS_VER_PI:
if(iLength != 1)
return false;
pstConaxInfo->stParam.Version = buf[2];
break;
case CA_SYS_ID_PI:
if(iLength != 2)
return false;
pstConaxInfo->stParam.CaSysId = (buf[2] << 8) | buf[3];
break;
case COUNTRY_INDICATOR_PI:
if(iLength != 2)
return false;
pstConaxInfo->stParam.CountryIndicatorValue = (buf[2] << 8) | buf[3];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -