输入的是ATR,通过解析输出TA、TB、TC、TD的信息。
似乎没有容错处理,~~~~(>_<)~~~~
#include <stdio.h> #define TA_BIT (1<<4) /**< TAx presence bit (bit 4, 0x10) */
#define TB_BIT (1<<5) /**< TBx presence bit (bit 5, 0x20) */
#define TC_BIT (1<<6) /**< TCx presence bit (bit 6, 0x40) */
#define TD_BIT (1<<7) /**< TDx presence bit (bit 7, 0x80) */ void atr_TS(unsigned char ch)
{
printf("TS: %02X\r\n", ch);
if(ch == 0x3B)
{
printf("\t正向约定\r\n");
}
else if(ch == 0x3F)
{
printf("\t反向约定\r\n");
}
else
{
printf("\tATR 错误\r\n");
}
}
void atr_T0(unsigned char ch)
{
printf("T0: %02X\r\n", ch); if ((ch & TA_BIT) == TA_BIT)
{
printf("\tTA1 存在\r\n");
}
if ((ch & TB_BIT) == TB_BIT)
{
printf("\tTB1 存在\r\n");
}
if ((ch & TC_BIT) == TC_BIT)
{
printf("\tTC1 存在\r\n");
}
if ((ch & TD_BIT) == TD_BIT)
{
printf("\tTD1 存在\r\n");
}
printf("\t历史字符数: %d\r\n", ch & 0x0f);
}
void atr_TA1(unsigned char ch)
{
int Di[] = { , , , , , , , ,
, , , , , , , };
int Fi[] = { , , , , , , , ,
, , , , , , , }; printf("TA1: %02X\r\n", ch);
printf("\t时钟速率转换因子Fi: %d\r\n", (ch >> ) & 0x0f);
printf("\t位速率调节因子Di: %d\r\n", (ch & 0x0f));
printf("\tFi/Di: %f\r\n",
(Fi[(ch>>)&0x0f]!= && Di[ch&0x0f]!=) ? (float)Fi[(ch>>)&0x0f]/(float)Di[ch&0x0f] : );
}
void atr_TB1(unsigned char ch)
{
printf("TB1: %02X\r\n", ch);
printf("\t编程电压 P 值: %d\r\n", ch & 0x1f);
printf("\t最大编程电流 I 值: %d\r\n", (ch >> ) & 0x03);
}
void atr_TC1(unsigned char ch)
{
printf("TC1: %02X\r\n", ch);
printf("\t额外保护时间: %d\r\n", ch);
}
void atr_TD1(unsigned char ch)
{
printf("TD1: %02X\r\n", ch); if ((ch & TA_BIT) == TA_BIT)
{
printf("\tTA2 存在\r\n");
}
if ((ch & TB_BIT) == TB_BIT)
{
printf("\tTB2 存在\r\n");
}
if ((ch & TC_BIT) == TC_BIT)
{
printf("\tTC2 存在\r\n");
}
if ((ch & TD_BIT) == TD_BIT)
{
printf("\tTD2 存在\r\n");
}
printf("\t后续信息交换所使用的协议类型: %d\r\n", ch & 0x0f);
}
void atr_TA2(unsigned char ch)
{
printf("TA2: %02X\r\n", ch);
printf("\t是否有能力改变它的操作模式: %s\r\n",
!!!(ch & 0x80) ? "是(0)" : "否(1)");
printf("\t协商模式 or 特定模式: %s\r\n",
!!!(ch & 0x80) ? "特定模式(0)" : "协商模式(1)");
printf("\t后续信息交换所使用的协议类型: %d\r\n", ch & 0x0f);
}
void atr_TB2(unsigned char ch)
{
printf("TB2: %02X\r\n", ch);
printf("\tIC卡所需的编程电压P的值PI2: %d\r\n", ch);
}
void atr_TC2(unsigned char ch)
{
printf("TC2: %02X\r\n", ch);
printf("\tT=0, 传输工作等待时间整数WI: %d\r\n", ch);
}
void atr_TD2(unsigned char ch)
{
printf("TD2: %02X\r\n", ch); if ((ch & TA_BIT) == TA_BIT)
{
printf("\tTA3 存在\r\n");
}
if ((ch & TB_BIT) == TB_BIT)
{
printf("\tTB3 存在\r\n");
}
if ((ch & TC_BIT) == TC_BIT)
{
printf("\tTC3 存在\r\n");
}
if ((ch & TD_BIT) == TD_BIT)
{
printf("\tTD3 存在\r\n");
}
printf("\t后续信息交换所使用的协议类型: %d\r\n", ch & 0x0f);
}
void atr_TA3(unsigned char ch)
{
printf("TA3: %02X\r\n", ch);
printf("\tT=1, IC卡的信息域大小整数IFSI: %d\r\n", ch);
}
void atr_TB3(unsigned char ch)
{
printf("TB3: %02X\r\n", ch);
printf("\tT=1, CWI: %d\r\n", ch & 0x0f);
printf("\tT=1, BWI: %d\r\n", (ch >> ) & 0x0f);
}
void atr_TC3(unsigned char ch)
{
printf("TC3: %02X\r\n", ch);
printf("\tT=1, 块错误校验码的类型: %d\r\n", ch & 0x01);
}
void atr_history(unsigned char *ch, int len)
{
int i;
printf("TKi:");
for(i = ; i < len; i++)
printf(" %02X", ch[i]);
printf("\r\n");
}
void atr_TCK(unsigned char ch)
{
printf("TCK: %02X\r\n", ch);
} #define STATE_PARSE_TS 1
#define STATE_PARSE_T0 2
#define STATE_PARSE_TA 3
#define STATE_PARSE_TB 4
#define STATE_PARSE_TC 5
#define STATE_PARSE_TD 6
#define STATE_PARSE_HIST_BYTES 7
#define STATE_PARSE_TCK 8
#define STATE_PARSE_END 255 int atr_parse(unsigned char *atr, int len)
{
unsigned char data;
unsigned char TCK = ;
unsigned char K = ;
unsigned char Yi = ;
int k, state, index, length, protocol;
unsigned char *ptr;
unsigned char hist_bytes[]; length = len;
ptr = atr;
state = STATE_PARSE_TS;
index = ;
k = ;
protocol = ; while( ptr < (atr + length) )
{
data = *ptr++;
if ( state != STATE_PARSE_TS )
{
TCK ^= data ;
} switch( state )
{
case STATE_PARSE_TS:
atr_TS(data);
state = STATE_PARSE_T0;
break;
case STATE_PARSE_T0:
atr_T0(data);
K = data & 0x0F;
Yi = data;
if ( data & 0x10 )
{
state = STATE_PARSE_TA;
}
else if ( data & 0x20 )
{
state = STATE_PARSE_TB;
}
else
{
if ( data & 0x40 )
{
state = STATE_PARSE_TC;
}
else if ( data & 0x80 )
{
state = STATE_PARSE_TD;
}
else
{
state = STATE_PARSE_HIST_BYTES;
}
}
break;
case STATE_PARSE_TA :
switch( index )
{
case : /* TA1 */
atr_TA1(data);
break;
case :
atr_TA2(data);
break;
case :
atr_TA3(data);
break;
}
if ( Yi & 0x20 )
{
state = STATE_PARSE_TB;
}
else if ( Yi & 0x40 )
{
state = STATE_PARSE_TC;
}
else if ( Yi & 0x80 )
{
state = STATE_PARSE_TD;
}
else
{
state = STATE_PARSE_HIST_BYTES;
}
break;
case STATE_PARSE_TB :
switch( index )
{
case : /* TB1 */
atr_TB1(data);
break ;
case : /* TB2 */
atr_TB2(data);
break ;
case : /* TB3 */
atr_TB3(data);
break;
}
if ( Yi & 0x40 )
{
state = STATE_PARSE_TC;
}
else if ( Yi & 0x80 )
{
state = STATE_PARSE_TD;
}
else
{
state = STATE_PARSE_HIST_BYTES;
}
break;
case STATE_PARSE_TC :
switch( index )
{
case : /* TC1 */
atr_TC1(data);
break;
case : /* TC2 */
atr_TC2(data);
break ;
case : /* TC3 */
atr_TC3(data);
break ;
}
if ( Yi & 0x80 )
{
state = STATE_PARSE_TD;
}
else
{
state = STATE_PARSE_HIST_BYTES;
}
break ;
case STATE_PARSE_TD :
Yi = data ;
switch( index++ )
{
case :
protocol = Yi & 0x0F;
atr_TD1(data);
break;
case :
atr_TD2(data);
break;
} if ( Yi & 0xF0 )
{
if ( Yi & 0x10 )
{
/* TAx character present */
state = STATE_PARSE_TA;
}
else if ( Yi & 0x20 )
{
/* TBx character present */
state = STATE_PARSE_TB;
}
else if ( Yi & 0x40 )
{
/* TCx character present */
state = STATE_PARSE_TC;
}
else if ( Yi & 0x80 )
{
/* TDx character present */
state = STATE_PARSE_TD;
}
else
{
state = STATE_PARSE_HIST_BYTES;
}
}
else
{
state = STATE_PARSE_HIST_BYTES;
}
break ;
case STATE_PARSE_HIST_BYTES:
if( K )
{
if( k < K )
{
hist_bytes[k++] = data;
if(k == K)
{
if(protocol > )
state = STATE_PARSE_TCK;
else
ptr = atr + length; atr_history(hist_bytes, k);
}
}
break;
}
case STATE_PARSE_TCK:
atr_TCK(data);
if ( !TCK )
{
}
atr_TCK(TCK);
ptr = atr + length;
break ;
}
if( state == STATE_PARSE_HIST_BYTES && K == && protocol == )
break;
} return ;
} int main(void)
{
//atr_TA2((0 << 7) | (0 << 4) | 0x01);
//atr_TA2((0 << 7) | (1 << 4) | 0x01);
//atr_TA2((1 << 7) | (0 << 4) | 0x01);
//atr_TA2((1 << 7) | (1 << 4) | 0x01);
//atr_TA1(0x11); //unsigned char atr1[] = {0x3B, 0xB5, 0x11, 0x00, 0x81, 0x31, 0x46, 0x15, 0x56, 0x20, 0x31, 0x2E, 0x50, 0x1E};
//unsigned char atr2[] = {0x3B, 0x9C, 0x11, 0x81, 0x21, 0x34, 0x53, 0x43, 0x20, 0x53, 0x56, 0x20, 0x31, 0x2E, 0x31, 0x20, 0x4E, 0x43, 0x0F};
//unsigned char atr3[] = {0x3B, 0x89, 0x40, 0x14, 0x47, 0x47, 0x32, 0x34, 0x4d, 0x35, 0x32, 0x38, 0x30};
unsigned char atr[] = {0x3f, 0x23, 0x00, 0x80, 0x69, 0xae}; atr_parse(atr, sizeof(atr)/sizeof(atr[])); return ;
}