调试读卡器时的一些问题【1】

项目场景:调试一款芯片作为读卡器使用

将一款芯片的代码一直到另一款新芯片上,实现的功能是7816读卡器功能

<技术小白,错误之处,烦请斧正>

问题描述

1、在初始化枚举时候对于主机下发的命令不能正确返回响应
2、正确返回ATR后,主机不下发 61 指令,所以无法进行ETU自校验

Bus Hound 6.01 capture on Windows Vista Service Pack 1 (x64). Complements of www.perisoft.net

  Device - Device ID (followed by the endpoint for USB devices)
            (25) Microsoft Usbccid Smartcard Reader (WUDF)
            (26) 智能卡筛选器驱动程序
            (27) 智能卡
  Length - Total transfer length
  Phase  - Phase Type
            CTL   USB control transfer       
            IN    Data in transfer           
            OUT   Data out transfer          
  Data   - Hex dump of the data transferred
  Descr  - Description of the phase
  Delta  - Elapsed time from the previous phase to the current phase
  Cmd... - Position in the captured data
  Time   - Time the phase occurred in hour:minute:second.millisec form


Device  Length    Phase  Data                                                                                                    Description                       Delta  Cmd.Phase.Ofs(rep)  Time        
------  --------  -----  ------------------------------------------------------------------------------------------------------  --------------------------------  -----  ------------------  ------------
  25.2        10  OUT    63 00 00 00  00 00 01 00  00 00                                                                         c.........                         37ms        12.1.0        15:48:47.336  
  25.1        10  IN     81 00 00 00  00 00 01 00  00 00                                                                         ..........                        992us        13.1.0        15:48:47.337  
  25.2        10  OUT    62 00 00 00  00 00 02 01  00 00                                                                         b.........                        9.6ms        14.1.0        15:48:47.347  
  25.1        22  IN     80 0c 00 00  00 00 02 00  00 00 3b 68  00 00 43 31  42 4f 4f 54  33 32                                  ..........;h..C1BOOT32             20ms        15.1.0        15:48:47.368  
  25.2        10  OUT    6c 00 00 00  00 00 03 00  00 00                                                                         l.........                         10ms        16.1.0        15:48:47.378  
  25.1        10  IN     81 00 00 00  00 00 03 40  00 00                                                                         .......@..                        1.0ms        17.1.0        15:48:47.379  
  25.2        26  OUT    6f 10 00 00  00 00 04 00  00 00 00 a4  04 00 0b a0  00 00 03 97  43 49 44 5f  01 00                     o...................CID_..        1.9ms        18.1.0        15:48:47.381  
  25.1        12  IN     80 02 00 00  00 00 04 00  00 00 6d 00                                                                   ..........m.                       10ms        19.1.0        15:48:47.391  

3、用命令设置新的ETU值后无法返回新的ATR
4、正确返回新的ATR后,61指令中的第10字节时钟是低速状态

Device  Length    Phase  Data                                                                                                    Description                       Delta  Cmd.Phase.Ofs(rep)  Time        
------  --------  -----  ------------------------------------------------------------------------------------------------------  --------------------------------  -----  ------------------  ------------
  25.2        10  OUT    63 00 00 00  00 00 29 00  00 00                                                                         c.....)...                        2.5sc         1.1.0        15:54:59.440  
  25.1        10  IN     81 00 00 00  00 00 29 00  00 00                                                                         ......)...                        995us         2.1.0        15:54:59.441  
  25.2        10  OUT    63 00 00 00  00 00 2a 00  00 00                                                                         c.....*...                        2.0ms         3.1.0        15:54:59.443  
  25.1        10  IN     81 00 00 00  00 00 2a 00  00 00                                                                         ......*...                        1.0ms         4.1.0        15:54:59.444  
  25.2        10  OUT    62 00 00 00  00 00 2b 01  00 00                                                                         b.....+...                         10ms         5.1.0        15:54:59.454  
  25.1        22  IN     80 0c 00 00  00 00 2b 00  00 00 3b 68  00 00 43 31  42 4f 4f 54  33 32                                  ......+...;h..C1BOOT32             20ms         6.1.0        15:54:59.475  
  25.2        15  OUT    61 05 00 00  00 00 2c 00  00 00 11 00  00 0a 00                                                         a.....,........                    10ms         7.1.0        15:54:59.485  
  25.1        15  IN     82 05 00 00  00 00 2c 00  00 00 11 00  00 0a 00                                                         ......,........                   992us         8.1.0        15:54:59.486  
  25.2        18  OUT    73 08 00 00  00 00 2d 00  00 00 fc 0d  00 00 80 25  00 00                                               s.....-........%..                994us         9.1.0        15:54:59.487  
  25.1        18  IN     84 08 00 00  00 00 2d 00  00 00 fc 0d  00 00 80 25  00 00                                               ......-........%..                1.0ms        10.1.0        15:54:59.488  
  25.2        15  OUT    6f 05 00 00  00 00 2e 00  00 00 c0 88  96 01 00                                                         o..............                   3.8sc        11.1.0        15:55:03.386  
  25.1        12  IN     80 02 00 00  00 00 2e 00  00 00 90 00                                                                   ............                       10ms        12.1.0        15:55:03.397  
  25.2        10  OUT    63 00 00 00  00 00 2f 00  00 00                                                                         c...../...                        3.3sc        13.1.0        15:55:06.783  
  25.1        10  IN     81 00 00 00  00 00 2f 00  00 00                                                                         ....../...                        1.0ms        14.1.0        15:55:06.784  
  25.2        10  OUT    63 00 00 00  00 00 30 00  00 00                                                                         c.....0...                        2.4ms        15.1.0        15:55:06.787  
  25.1        10  IN     81 00 00 00  00 00 30 00  00 00                                                                         ......0...                        1.0ms        16.1.0        15:55:06.788  
  25.2        10  OUT    62 00 00 00  00 00 31 01  00 00                                                                         b.....1...                         10ms        17.1.0        15:55:06.798  
  25.1        23  IN     80 0d 00 00  00 00 31 00  00 00 3b 78  96 00 00 43  31 42 4f 4f  54 33 32                               ......1...;x...C1BOOT32            26ms        18.1.0        15:55:06.825  
  25.2        14  OUT    6f 04 00 00  00 00 32 00  00 00 ff 10  11 fe                                                            o.....2.......                     11ms        19.1.0        15:55:06.836  
  25.1        14  IN     80 04 00 00  00 00 32 00  00 00 ff 10  11 fe                                                            ......2.......                     12ms        20.1.0        15:55:06.848  
  25.2        15  OUT    61 05 00 00  00 00 33 00  00 00 11 00  00 0a 00                                                         a.....3........                   925us        21.1.0        15:55:06.849  
  25.1        15  IN     82 05 00 00  00 00 33 00  00 00 11 00  00 0a 00                                                         ......3........                   1.0ms        22.1.0        15:55:06.850  
  25.2        18  OUT    73 08 00 00  00 00 34 00  00 00 fc 0d  00 00 80 25  00 00                                               s.....4........%..                1.0ms        23.1.0        15:55:06.851  
  25.1        18  IN     84 08 00 00  00 00 34 00  00 00 fc 0d  00 00 80 25  00 00                                               ......4........%..                980us        24.1.0        15:55:06.852  


原因分析:

1、原因可能是设备中没有处理主机下发的数据或者设备处理错了相应的命令。(代码写错了、、、、、、)
7816的协议一般是主机发送5字节收一个INS,判断是否继续发送。有的指令是仅收SW。所以改写处理 6F 指令的函数

2、61命令涉及到读卡器自动修改通信速率,主机不下发命令应该是设备描述符中相应的位置没有设置正确
3、设置新的速度模式后需复位卡片,可能是在62命令处理不当,导致没有返回正确响应
4、新的速率的ATR成功返回后,主机下发的命令没有更新,应该与设备描述符设置有关


解决方案:

1、修改接收到命令后的处理过程,如果不了解怎么处理可能请教大神。。。。。(下面是我自己的代码,)

//此函数用于处理 6F 命令
void user_custom_commands(void)
{
	U16 data_len = (U16)((message_data[2]<<8) | message_data[1]);
	unsigned char sw[2];

	// send command header to card   将命令发送到卡
	memcpy(data_buff,(U8*)(SPECIAL_RAM_BASE + EP1_ADDR + 10),data_len);
	
	if(message_data[10] == 0xff)
	{
		send_data(data_buff, 4);
		receive_data(recv_buff, 4);
		memcpy(message_data + 10, recv_buff, 4);
		message_data[0] = 0x80;
		ep1_send(EP1_ADDR,14);
		
		return ;
	}
	
	
	if(data_len < 5)
	{
		send_data(data_buff, 4);
	}
	else
	{
		send_data(data_buff, 5);
	}
	
	if(0 == receive_byte(sw))
	{
		goto timeout_exit;
	}
	
	
	//Null
	while(sw[0] == 0x60)
	{
		SCITCR = 0x601B3F00;
		while(!(SCISR & SCISR_RDRF) & !(SCITCR & SCISR_CNTOR));
		SCITCR = 0;
		if(0 == receive_byte(sw))
		{
			goto timeout_exit;
		}
	}
	
	//0x6X or 0x9X
	if(((sw[0] & 0xf0) == 0x60) || ((sw[0] & 0xf0) == 0x90))
	{
		if(0 == receive_byte(sw+1))
		{
			goto timeout_exit;
		}
		
		data_len = 2;
		memcpy(message_data + 10, sw, data_len);
		
		message_data[0] = 0x80;	//RDR_to_PC_SlotStatus
		message_data[1] = (unsigned char)(data_len & 0xff);
		message_data[2] = (unsigned char)(data_len >> 8);
		message_data[3] = 0x00;
		message_data[4] = 0x00;
		message_data[7] = 0x00;
		message_data[8] = 0x00;
		message_data[9] = 0x00;
		
		data_len += 10;
		
		ep1_send(EP1_ADDR,data_len);
		
		return ;
	}
	
	//CMD
	if(sw[0] != data_buff[1])
	{
		goto timeout_exit;
	}
	
	// 判断长度
	if(data_len == 5)
	{
		receive_data(recv_buff, data_buff[4] + 2);
		//get_procedure_byte(sw, 0);
		
		memcpy(message_data + 10, recv_buff, data_buff[4] + 2);
		
		data_len = data_buff[4];
		data_len += 2;
		message_data[0] = 0x80;	//RDR_to_PC_SlotStatus
		message_data[1] = (unsigned char)(data_len & 0xff);
		message_data[2] = (unsigned char)(data_len >> 8);
		message_data[3] = 0x00;
		message_data[4] = 0x00;
		message_data[7] = 0x00;
		message_data[8] = 0x00;
		message_data[9] = 0x00;
		data_len += 10;
		
		ep1_send(EP1_ADDR,data_len);
		
		return;
	}
	else if(data_len > 5)
	{
		send_data(data_buff + 5, data_len - 5);
		
		if(true != get_procedure_byte(sw, data_buff[1]))
		{
			goto timeout_exit;
		}
		
		if(((sw[0] & 0x60) == 0x60) || ((sw[0] & 0x90) == 0x90))
		{
			data_len = 2;
			memcpy(message_data + 10, sw, data_len);
			
			message_data[0] = 0x80;	//RDR_to_PC_SlotStatus
			message_data[1] = (unsigned char)(data_len & 0xff);
			message_data[2] = (unsigned char)(data_len >> 8);
			message_data[3] = 0x00;
			message_data[4] = 0x00;
			message_data[7] = 0x00;
			message_data[8] = 0x00;
			message_data[9] = 0x00;
			
			data_len += 10;
			
			ep1_send(EP1_ADDR,data_len);
			
			return ;
		}
	}
	

	
timeout_exit:
	SCISR |= SCISR_WTF;
	SCICR2 &= ~SCICR2_WTEN;
	message_data[7] = SLOT_STATUS_ERROR;
	message_data[8] = ICC_MUTE;

	ep1_send(EP1_ADDR,10);
	
	//usb_send_ep3(CARD_REMOVE_NOTICE);
    last_state = 0;
    slot_state = 0;
	
	return;
}

2、主机不下发61命令修改设备描述符的 dwFeatures 信息,此信息是决定是否自动修改速率的配置
在这里插入图片描述

3、修改62命令的处理过程

case 0x62:                 // PC_to_RDR_IccPowerOn
			{
				/*没有一下两行代码是不行的*/
				SCICR1 |= SCICR1_SRST; //复位SCI模块,我是“两句代码的第一行”
				SCI_Master_Init();  //重新初始化,我是“两句代码的第二行”
				Activate_Card();   //连接卡片
				get_ATR((unsigned char*)&message_data[10], &T, &ATR_Len);  //获取ATR
				
				message_data[0] = 0x80;
				message_data[1] = ATR_Len;
				message_data[7] = 0;
				message_data[8] = 0;
					
				ep1_send(EP1_ADDR,ATR_Len + 10); //将数据返回到上位机
			}
			break;

4、此与 dwMaxDataRate参数有关,表明设备支持最大的速率
在这里插入图片描述

其他

1、61命令的处理方式

unsigned short etu_clk[256]={
	0,	372,	186,	93,		0,		0,		0,		0,	31,		0,	0,0,0,0,0,0,
	0,	372,	186,	93,		0,		0,		0,		0,	31,		0,	0,0,0,0,0,0,
	0,	558,	279, 	0,		0,		0,		0,		0,	0,		0,	0,0,0,0,0,0,
	0,	744,	372,	186,	93,		0,		0,		0,	62,		0,	0,0,0,0,0,0,
	0,	1116,	558,	279,	0,		0,		0,		0,	93,		0,	0,0,0,0,0,0,
	0,	1488,	744,	372,	186,	93,		0,		0,	124,	0,	0,0,0,0,0,0,
	0,	1860,	930,	465,	0,		0,		0,		0,	155,	93,	0,0,0,0,0,0,
	0,	0,		0,		0,		0,		0,		0,		0,	0,		0,	0,0,0,0,0,0,
	0,	0,		0,		0,		0,		0,		0,		0,	0,		0,	0,0,0,0,0,0,
	0,	512,	256,	128,	64,		32,		16,		8,	0,		0,	0,0,0,0,0,0,
	0,	768,	384,	192,	96,		48,		24,		12,	64,		0,	0,0,0,0,0,0,
	0,	1024,	512,	256,	128,	64,		32,		16,	0,		0,	0,0,0,0,0,0,
	0,	1536,	768,	384,	192,	96,		48,		24,	128,	0,	0,0,0,0,0,0,
	0,	2048,	1024,	512,	256,	128,	64,		32,	0,		0,	0,0,0,0,0,0,
	0,	0,		0,		0,		0,		0,		0,		0,	0,		0,	0,0,0,0,0,0,
	0,	0,		0,		0,		0,		0,		0,		0,	0,		0,	0,0,0,0,0,0	
};

case 0x61:				//PC_to_RDR_SetParameters
			{
				etu_parameter = etu_clk[message_data[10]];
				if(etu_parameter==0)
				{
					message_data[0] = 0x82;	//RDR_to_PC_Parameters
					message_data[1] = 0x00;
					message_data[2] = 0x00;
					message_data[3] = 0x00;
					message_data[4] = 0x00;	
					message_data[9] = message_data[7];
					message_data[7] = 0x40;	
					message_data[8] = FI_DI_PAIR_INVALID_OR_NOT_SUPPORTED;

					ep1_send(EP1_ADDR,10);
				}
				else
				{
					//set etu clock
					SCIECR = etu_parameter;

					//set convetion
					if(message_data[11]) SCICR1 |= SCICR1_CONV;
					else SCICR1 &= ~SCICR1_CONV;

					//set extra gard time
					if(message_data[12]==255) SCIGTR = 12;
					else SCIGTR = (U16)(12+message_data[12]);

					//set wait time
					WT = 960 * /*(U32)message_data[13]*/ 10 * (372/etu_parameter) * 4; // 4M????3.4?
					SCICWTR = WT;

					//set stop clock level
					if(message_data[14]==2) SCICR2 |= SCICR2_CSHL;
					else SCICR2 &= ~SCICR2_CSHL;

					message_data[0] = 0x82;	//RDR_to_PC_Parameters
					message_data[9] = message_data[7];
					message_data[7] = 0x00;	
					message_data[8] = 0x00;
					
					ep1_send(EP1_ADDR,10+message_data[1]);
				}
			}
			break;

2、设备描述符

static unsigned char ConfigurationDescriptor[0x56+7] = 
{
	//*Configuration Descriptor
	0x09,  					//bLength
	0x02,  					//bDescriptorType	: Configuration
	//0x56, 0x00, 		//wTotalLength
	0x5d, 0x00, 		//wTotalLength
	0x01, 					//bNumInterfaces
	0x01, 					//bConfigurationValue
	0x00, 					//iConfiguration
	0x80, 					//bmAttributes
	0x64,					//MaxPower
	//Interface Descriptor
	0x09,  					//bLength 
	0x04,  					//bDescriptorType	: Interface 
	0x00,  					//bInterfaceNumber
	0x00,  					//bAlternateSetting 
	0x02,  					//bNumEndpoints: In and  Ou  
	//0x03,  					//bNumEndpoints: In and  Ou  
	0x0b, 					//bInterfaceClass	: Smart card
	0x00, 					//bInterfaceSubClass
	0x00, 					//bInterfaceProtocol: Bulk
	0x00,					//iInterface
	//Class Descriptor
	0x36,  					//bLength 
	0x21,   				//bDescriptorType	: CCID
	0x10, 0x01, 			//bcdCCID			: v1.1
	0x00,   				//bMaxSlotIndex	 
	0x01, 					//bVoltageSupport
	0x01, 0x00, 0x00, 0x00, //dwProtocols		: T=0
	0xfc, 0x0d, 0x00, 0x00, //dwDefaultClock	: 3.58MHz
	0xfc, 0x0d, 0x00, 0x00, //dwMaximumClock	: 3.58MHz
	0x00,  					//bNumClockSupported: should be non-zero according to ccid driver
	//0x01,  					//bNumClockSupported: should be non-zero according to ccid driver
	0x80, 0x25, 0x00, 0x00, //dwDataRate
	//0x80, 0x25, 0x00, 0x00, //dwMaxDataRate
	0x06, 0x6a, 0x03, 0x00, //dwMaxDataRate
	0x00,   				//bNumDataRatesSupported: should be non-zero according to ccid driver
	0x00, 0x00, 0x00, 0x00, //dwMaxIFSD
	0x00, 0x00, 0x00, 0x00, //dwSynchProtocols
	0x00, 0x00, 0x00, 0x00, //dwMechanical
	//0x40, 0x08, 0x02, 0x00, //dwFeatures
	0x00, 0x00, 0x01, 0x00, //dwFeatures
	0x0f, 0x01, 0x00, 0x00, //dwMaxCCIDMessageLength: 271
	0xff, 					//bClassGetResponse
	0xff, 					//bClassEnvelope
	0x00, 0x00, 			//wLcdLayout
	0x00, 					//bPINSupport
	0x01,					//bMaxCCIDBusySlots
	//Endpoint Descriptors
	0x07, 0x05, 0x81, 0x02, 0x40, 0x00, 0x00,
	0x07, 0x05, 0x02, 0x02, 0x40, 0x00, 0x00,
	0x07, 0x05, 0x83, 0x03, 0x08, 0x00, 0x18,
};

3、dwMaxDataRate的一些值

static unsigned char Response_To_GET_DATA_RATES[76] = {
	0x80, 0x25, 0x00, 0x00,	//9600: 			372 clocks/etu
	0x1f, 0x32, 0x00, 0x00,	//12831(12800): 	279 clocks/etu
	0xa0, 0x36, 0x00, 0x00,	//13984(13950): 	256 clocks/etu
	0xd5, 0x48, 0x00, 0x00,	//18645(18600): 	192 clocks/etu
	0x2f, 0x4b, 0x00, 0x00,	//19247(19200): 	186 clocks/etu
	0x38, 0x5a, 0x00, 0x00,	//23096(23040): 	155 clocks/etu
	0x40, 0x6d, 0x00, 0x00,	//27968(27900): 	128 clocks/etu
	0xc6, 0x70, 0x00, 0x00,	//28870(28800): 	124 clocks/etu
	0xab, 0x91, 0x00, 0x00,	//37291(37200): 	96 clocks/etu
	0x5e, 0x96, 0x00, 0x00,	//38494(38400): 	93 clocks/etu
	0x81, 0xda, 0x00, 0x00,	//55937(55800): 	64 clocks/etu
	0x8d, 0xe1, 0x00, 0x00,	//57741(57600): 	62 clocks/etu
	0x57, 0x23, 0x01, 0x00,	//74583(74400): 	48 clocks/etu
	0x03, 0xb5, 0x01, 0x00,	//111875(111600): 	32 clocks/etu
	0x1b, 0xc3, 0x01, 0x00,	//115483(115200): 	31 clocks/etu
	0xae, 0x46, 0x02, 0x00,	//149166(148800): 	24 clocks/etu
	0x06, 0x6a, 0x03, 0x00, //223750(223200):	16 clocks/etu
	0x5d, 0x8d, 0x04, 0x00, //298333(297600):	12 clocks/etu
	0x0c, 0xd4, 0x06, 0x00  //447500(446400):	8 clocks/etu
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值