输入的是ATR,通过解析输出TA、TB、TC、TD的信息。

似乎没有容错处理,~~~~(>_<)~~~~

  1. #include <stdio.h>
  2.  
  3. #define TA_BIT (1<<4) /**< TAx presence bit (bit 4, 0x10) */
  4. #define TB_BIT (1<<5) /**< TBx presence bit (bit 5, 0x20) */
  5. #define TC_BIT (1<<6) /**< TCx presence bit (bit 6, 0x40) */
  6. #define TD_BIT (1<<7) /**< TDx presence bit (bit 7, 0x80) */
  7.  
  8. void atr_TS(unsigned char ch)
  9. {
  10. printf("TS: %02X\r\n", ch);
  11. if(ch == 0x3B)
  12. {
  13. printf("\t正向约定\r\n");
  14. }
  15. else if(ch == 0x3F)
  16. {
  17. printf("\t反向约定\r\n");
  18. }
  19. else
  20. {
  21. printf("\tATR 错误\r\n");
  22. }
  23. }
  24. void atr_T0(unsigned char ch)
  25. {
  26. printf("T0: %02X\r\n", ch);
  27.  
  28. if ((ch & TA_BIT) == TA_BIT)
  29. {
  30. printf("\tTA1 存在\r\n");
  31. }
  32. if ((ch & TB_BIT) == TB_BIT)
  33. {
  34. printf("\tTB1 存在\r\n");
  35. }
  36. if ((ch & TC_BIT) == TC_BIT)
  37. {
  38. printf("\tTC1 存在\r\n");
  39. }
  40. if ((ch & TD_BIT) == TD_BIT)
  41. {
  42. printf("\tTD1 存在\r\n");
  43. }
  44. printf("\t历史字符数: %d\r\n", ch & 0x0f);
  45. }
  46. void atr_TA1(unsigned char ch)
  47. {
  48. int Di[] = { , , , , , , , ,
  49. , , , , , , , };
  50. int Fi[] = { , , , , , , , ,
  51. , , , , , , , };
  52.  
  53. printf("TA1: %02X\r\n", ch);
  54. printf("\t时钟速率转换因子Fi: %d\r\n", (ch >> ) & 0x0f);
  55. printf("\t位速率调节因子Di: %d\r\n", (ch & 0x0f));
  56. printf("\tFi/Di: %f\r\n",
  57. (Fi[(ch>>)&0x0f]!= && Di[ch&0x0f]!=) ? (float)Fi[(ch>>)&0x0f]/(float)Di[ch&0x0f] : );
  58. }
  59. void atr_TB1(unsigned char ch)
  60. {
  61. printf("TB1: %02X\r\n", ch);
  62. printf("\t编程电压 P 值: %d\r\n", ch & 0x1f);
  63. printf("\t最大编程电流 I 值: %d\r\n", (ch >> ) & 0x03);
  64. }
  65. void atr_TC1(unsigned char ch)
  66. {
  67. printf("TC1: %02X\r\n", ch);
  68. printf("\t额外保护时间: %d\r\n", ch);
  69. }
  70. void atr_TD1(unsigned char ch)
  71. {
  72. printf("TD1: %02X\r\n", ch);
  73.  
  74. if ((ch & TA_BIT) == TA_BIT)
  75. {
  76. printf("\tTA2 存在\r\n");
  77. }
  78. if ((ch & TB_BIT) == TB_BIT)
  79. {
  80. printf("\tTB2 存在\r\n");
  81. }
  82. if ((ch & TC_BIT) == TC_BIT)
  83. {
  84. printf("\tTC2 存在\r\n");
  85. }
  86. if ((ch & TD_BIT) == TD_BIT)
  87. {
  88. printf("\tTD2 存在\r\n");
  89. }
  90. printf("\t后续信息交换所使用的协议类型: %d\r\n", ch & 0x0f);
  91. }
  92. void atr_TA2(unsigned char ch)
  93. {
  94. printf("TA2: %02X\r\n", ch);
  95. printf("\t是否有能力改变它的操作模式: %s\r\n",
  96. !!!(ch & 0x80) ? "是(0)" : "否(1)");
  97. printf("\t协商模式 or 特定模式: %s\r\n",
  98. !!!(ch & 0x80) ? "特定模式(0)" : "协商模式(1)");
  99. printf("\t后续信息交换所使用的协议类型: %d\r\n", ch & 0x0f);
  100. }
  101. void atr_TB2(unsigned char ch)
  102. {
  103. printf("TB2: %02X\r\n", ch);
  104. printf("\tIC卡所需的编程电压P的值PI2: %d\r\n", ch);
  105. }
  106. void atr_TC2(unsigned char ch)
  107. {
  108. printf("TC2: %02X\r\n", ch);
  109. printf("\tT=0, 传输工作等待时间整数WI: %d\r\n", ch);
  110. }
  111. void atr_TD2(unsigned char ch)
  112. {
  113. printf("TD2: %02X\r\n", ch);
  114.  
  115. if ((ch & TA_BIT) == TA_BIT)
  116. {
  117. printf("\tTA3 存在\r\n");
  118. }
  119. if ((ch & TB_BIT) == TB_BIT)
  120. {
  121. printf("\tTB3 存在\r\n");
  122. }
  123. if ((ch & TC_BIT) == TC_BIT)
  124. {
  125. printf("\tTC3 存在\r\n");
  126. }
  127. if ((ch & TD_BIT) == TD_BIT)
  128. {
  129. printf("\tTD3 存在\r\n");
  130. }
  131. printf("\t后续信息交换所使用的协议类型: %d\r\n", ch & 0x0f);
  132. }
  133. void atr_TA3(unsigned char ch)
  134. {
  135. printf("TA3: %02X\r\n", ch);
  136. printf("\tT=1, IC卡的信息域大小整数IFSI: %d\r\n", ch);
  137. }
  138. void atr_TB3(unsigned char ch)
  139. {
  140. printf("TB3: %02X\r\n", ch);
  141. printf("\tT=1, CWI: %d\r\n", ch & 0x0f);
  142. printf("\tT=1, BWI: %d\r\n", (ch >> ) & 0x0f);
  143. }
  144. void atr_TC3(unsigned char ch)
  145. {
  146. printf("TC3: %02X\r\n", ch);
  147. printf("\tT=1, 块错误校验码的类型: %d\r\n", ch & 0x01);
  148. }
  149. void atr_history(unsigned char *ch, int len)
  150. {
  151. int i;
  152. printf("TKi:");
  153. for(i = ; i < len; i++)
  154. printf(" %02X", ch[i]);
  155. printf("\r\n");
  156. }
  157. void atr_TCK(unsigned char ch)
  158. {
  159. printf("TCK: %02X\r\n", ch);
  160. }
  161.  
  162. #define STATE_PARSE_TS 1
  163. #define STATE_PARSE_T0 2
  164. #define STATE_PARSE_TA 3
  165. #define STATE_PARSE_TB 4
  166. #define STATE_PARSE_TC 5
  167. #define STATE_PARSE_TD 6
  168. #define STATE_PARSE_HIST_BYTES 7
  169. #define STATE_PARSE_TCK 8
  170. #define STATE_PARSE_END 255
  171.  
  172. int atr_parse(unsigned char *atr, int len)
  173. {
  174. unsigned char data;
  175. unsigned char TCK = ;
  176. unsigned char K = ;
  177. unsigned char Yi = ;
  178. int k, state, index, length, protocol;
  179. unsigned char *ptr;
  180. unsigned char hist_bytes[];
  181.  
  182. length = len;
  183. ptr = atr;
  184. state = STATE_PARSE_TS;
  185. index = ;
  186. k = ;
  187. protocol = ;
  188.  
  189. while( ptr < (atr + length) )
  190. {
  191. data = *ptr++;
  192. if ( state != STATE_PARSE_TS )
  193. {
  194. TCK ^= data ;
  195. }
  196.  
  197. switch( state )
  198. {
  199. case STATE_PARSE_TS:
  200. atr_TS(data);
  201. state = STATE_PARSE_T0;
  202. break;
  203. case STATE_PARSE_T0:
  204. atr_T0(data);
  205. K = data & 0x0F;
  206. Yi = data;
  207. if ( data & 0x10 )
  208. {
  209. state = STATE_PARSE_TA;
  210. }
  211. else if ( data & 0x20 )
  212. {
  213. state = STATE_PARSE_TB;
  214. }
  215. else
  216. {
  217. if ( data & 0x40 )
  218. {
  219. state = STATE_PARSE_TC;
  220. }
  221. else if ( data & 0x80 )
  222. {
  223. state = STATE_PARSE_TD;
  224. }
  225. else
  226. {
  227. state = STATE_PARSE_HIST_BYTES;
  228. }
  229. }
  230. break;
  231. case STATE_PARSE_TA :
  232. switch( index )
  233. {
  234. case : /* TA1 */
  235. atr_TA1(data);
  236. break;
  237. case :
  238. atr_TA2(data);
  239. break;
  240. case :
  241. atr_TA3(data);
  242. break;
  243. }
  244. if ( Yi & 0x20 )
  245. {
  246. state = STATE_PARSE_TB;
  247. }
  248. else if ( Yi & 0x40 )
  249. {
  250. state = STATE_PARSE_TC;
  251. }
  252. else if ( Yi & 0x80 )
  253. {
  254. state = STATE_PARSE_TD;
  255. }
  256. else
  257. {
  258. state = STATE_PARSE_HIST_BYTES;
  259. }
  260. break;
  261. case STATE_PARSE_TB :
  262. switch( index )
  263. {
  264. case : /* TB1 */
  265. atr_TB1(data);
  266. break ;
  267. case : /* TB2 */
  268. atr_TB2(data);
  269. break ;
  270. case : /* TB3 */
  271. atr_TB3(data);
  272. break;
  273. }
  274. if ( Yi & 0x40 )
  275. {
  276. state = STATE_PARSE_TC;
  277. }
  278. else if ( Yi & 0x80 )
  279. {
  280. state = STATE_PARSE_TD;
  281. }
  282. else
  283. {
  284. state = STATE_PARSE_HIST_BYTES;
  285. }
  286. break;
  287. case STATE_PARSE_TC :
  288. switch( index )
  289. {
  290. case : /* TC1 */
  291. atr_TC1(data);
  292. break;
  293. case : /* TC2 */
  294. atr_TC2(data);
  295. break ;
  296. case : /* TC3 */
  297. atr_TC3(data);
  298. break ;
  299. }
  300. if ( Yi & 0x80 )
  301. {
  302. state = STATE_PARSE_TD;
  303. }
  304. else
  305. {
  306. state = STATE_PARSE_HIST_BYTES;
  307. }
  308. break ;
  309. case STATE_PARSE_TD :
  310. Yi = data ;
  311. switch( index++ )
  312. {
  313. case :
  314. protocol = Yi & 0x0F;
  315. atr_TD1(data);
  316. break;
  317. case :
  318. atr_TD2(data);
  319. break;
  320. }
  321.  
  322. if ( Yi & 0xF0 )
  323. {
  324. if ( Yi & 0x10 )
  325. {
  326. /* TAx character present */
  327. state = STATE_PARSE_TA;
  328. }
  329. else if ( Yi & 0x20 )
  330. {
  331. /* TBx character present */
  332. state = STATE_PARSE_TB;
  333. }
  334. else if ( Yi & 0x40 )
  335. {
  336. /* TCx character present */
  337. state = STATE_PARSE_TC;
  338. }
  339. else if ( Yi & 0x80 )
  340. {
  341. /* TDx character present */
  342. state = STATE_PARSE_TD;
  343. }
  344. else
  345. {
  346. state = STATE_PARSE_HIST_BYTES;
  347. }
  348. }
  349. else
  350. {
  351. state = STATE_PARSE_HIST_BYTES;
  352. }
  353. break ;
  354. case STATE_PARSE_HIST_BYTES:
  355. if( K )
  356. {
  357. if( k < K )
  358. {
  359. hist_bytes[k++] = data;
  360. if(k == K)
  361. {
  362. if(protocol > )
  363. state = STATE_PARSE_TCK;
  364. else
  365. ptr = atr + length;
  366.  
  367. atr_history(hist_bytes, k);
  368. }
  369. }
  370. break;
  371. }
  372. case STATE_PARSE_TCK:
  373. atr_TCK(data);
  374. if ( !TCK )
  375. {
  376. }
  377. atr_TCK(TCK);
  378. ptr = atr + length;
  379. break ;
  380. }
  381. if( state == STATE_PARSE_HIST_BYTES && K == && protocol == )
  382. break;
  383. }
  384.  
  385. return ;
  386. }
  387.  
  388. int main(void)
  389. {
  390. //atr_TA2((0 << 7) | (0 << 4) | 0x01);
  391. //atr_TA2((0 << 7) | (1 << 4) | 0x01);
  392. //atr_TA2((1 << 7) | (0 << 4) | 0x01);
  393. //atr_TA2((1 << 7) | (1 << 4) | 0x01);
  394. //atr_TA1(0x11);
  395.  
  396. //unsigned char atr1[] = {0x3B, 0xB5, 0x11, 0x00, 0x81, 0x31, 0x46, 0x15, 0x56, 0x20, 0x31, 0x2E, 0x50, 0x1E};
  397. //unsigned char atr2[] = {0x3B, 0x9C, 0x11, 0x81, 0x21, 0x34, 0x53, 0x43, 0x20, 0x53, 0x56, 0x20, 0x31, 0x2E, 0x31, 0x20, 0x4E, 0x43, 0x0F};
  398. //unsigned char atr3[] = {0x3B, 0x89, 0x40, 0x14, 0x47, 0x47, 0x32, 0x34, 0x4d, 0x35, 0x32, 0x38, 0x30};
  399. unsigned char atr[] = {0x3f, 0x23, 0x00, 0x80, 0x69, 0xae};
  400.  
  401. atr_parse(atr, sizeof(atr)/sizeof(atr[]));
  402.  
  403. return ;
  404. }

IC卡复位应答ATR解析的更多相关文章

  1. IC卡复位应答ATR的数据元和它们的意义

    ISO/IEC 7816-3标准中对ATR的数据串和数据元做了规定和描述.ATR的数据元和它们的意义: 数据元 说明 TS 起始字符 T0 格式字符 TA1,TB1,TC1,TD1,... 接口字符 ...

  2. 复位应答ATR的基本结构和数据元

    根据定义,复位应答是一系列字节的值,这些字节是由卡作为对复位命令的响应发送给接口设备的 ,在I/O电路上,每个字节在一个异步字符中传输.每个成功的复位操作,都会导致I/O上的一个初始字符TS,TS后面 ...

  3. EMV卡复位应答的时间特性 ---ISO7816协议

    1.冷复位的时间特性 图1 如图1所示: T0为200clk 从T0结束到RST变为高电平为40000-45000个clock 从RST变为高电平后,卡片必须在400-40000个clock之间应答, ...

  4. IC卡热复位时序

    热复位(warm reset):在时钟CLK和电源电压VCC处于激活状态的前提下,IC卡收到复位信号时产生的复位. 冷复位过程之后,如果收到的复位应答信号不满足规定,终端将启动热复位并从IC卡获得复位 ...

  5. IC卡冷复位时序

    冷复位(cold reset):当提供给IC卡的电源电压和其他信号从静止状态中复苏且收到复位信号后,IC卡产生的复位. 在触点激活后,终端将发出一个冷复位信号,并从IC卡获得一个复位应答信号,过程如下 ...

  6. IC卡接口芯片TDA8007的读写器设计

    摘要:阐述T=0传输协议,给出IC卡读写器中使用的IC卡APDU指令流程和原理框图:重点介绍其中的IC卡接口芯片Philips的TDA8007,给出通过TDA8007对CPU IC卡上下电过程.具体程 ...

  7. 智能卡 ATR解析

    如果终端不支持IC卡支持的其它传输协议以及传输参数值,IC卡应该有能力用基本ATR定义的模式和终端进行交互. 终端如果无法满足IC卡回送ATR中定义的传输模式,将发送一个热复位信号,或将IC卡置为静止 ...

  8. IC卡

    本词条由“科普中国”百科科学词条编写与应用工作项目 审核 . IC卡 (Integrated Circuit Card,集成电路卡),也称智能卡(Smart card).智慧卡(Intelligent ...

  9. 智能IC卡与终端(读卡器)之间的传输协议

    1.有两种协议 T=0,异步半双工字符传输协议 T=1,异步半双工块传输协议 终端一般都支持这两种协议,IC卡可以选择支持其中的一种.(因为终端可能需要面对各种类型的卡片,所以必须两种协议都支持,而卡 ...

随机推荐

  1. FPGA作为从机与STM32进行SPI协议通信---Verilog实现 [转]

    一.SPI协议简要介绍 SPI,是英语Serial Peripheral Interface的缩写,顾名思义就是串行外围设备接口.SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用 ...

  2. SqlServer索引使用及维护

    在应用系统中,尤其在联机事物处理系统中,对数据查询及处理速度已成为衡量应用系统的标准. 而采用索引来加快数据处理速度也成为广大数据库用户所接受的优化方法. 在良好的数据库设计基础上,能够有效地索引是S ...

  3. Xcode6如何自己添加pch文件?

    1.先自己添加.pch文件(右击new file) 2.最重要的一步,如何让工程识别! 在Build settings里搜索Prefix Header, 第一个箭头选择yes,第二箭头把你的pch的路 ...

  4. 三、Python 变量、运算符、表达式

    3.1 变量 变量是计算机内存中的一块区域,变量可以存储规定范围内的值,值可以改变,其实是将值在内存中保存地址位交给变量,变量去内存中获取,重新赋值,改变的就是内存地址位. 命名: 变量名由字母.数字 ...

  5. MVC教程相关

    本教程所有文章导航 本系列共10篇文章,翻译自Asp.Net MVC4 官方教程,由于本系列文章言简意赅,篇幅适中,从一个示例开始讲解,全文最终完成了一个管理影片的小系统,非常适合新手入门Asp.Ne ...

  6. silverlight导出excel

    开发导出excel,首先需要添加项目引用. Microsoft.CSharp 这个是应用dynamic的前提. 在代码页,需要添加引用 using System.Runtime.InteropServ ...

  7. Java反射机制专题

    ·Java Reflection Reflection(反射)是被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方 ...

  8. cookie 保存导航菜单的展开状态

    菜单展开状态保存,最开始是用session来存的,用session存没点击一次菜单就会多次访问后台页面,影响页面加载速度,后来改用js的cookie来存:代码如下 //获取cookie         ...

  9. IOS的Crash情况在Crashlytics平台上统计解决方案的一点遗憾(截止到2015年6月14日)

    平台针对特定版本的monkey操作后数量统计,按时间段定时去获取,最后根据操作批次出具分析报告: 问题是crashlytics平台仅提供一个BS登录查看WEB后台,所以无法通过API或者DB去直接获取 ...

  10. 获取局域网中指定IP或是主机名称的所有文件夹及其搜索文件

    最近做个功能在局域网中所有指定文件,于是花了点精力完成了部分功能,先贴上 using System; using System.Collections.Generic; using System.Co ...