Chinaunix首页 | 论坛 | 博客
  • 博客访问: 7553696
  • 博文数量: 961
  • 博客积分: 15795
  • 博客等级: 上将
  • 技术积分: 16612
  • 用 户 组: 普通用户
  • 注册时间: 2010-08-07 14:23
文章分类

全部博文(961)

文章存档

2016年(1)

2015年(61)

2014年(41)

2013年(51)

2012年(235)

2011年(391)

2010年(181)

分类: 嵌入式

2012-12-26 10:32:18

建立应用列表有两种方法PSE目录选择方法和AID选择方法后者比较简单,看规范容易理解这篇文章只介绍目录选择方法.

 

步骤是这样的:

1 终端选择PSE,从卡片返回的FCI中读到SFI.

PSE本身是一个EF文件,所以通过SFI来定位, EF文件又是由很多记录组成通过read record来读取记录的个数不一定终端应该从第一条记录一直读,一直读到卡片返回6A83. 格式如下图:


终端通过read record读取SFI中的所有记录每读到一条记录就去找入口看上图可知每一条记录是一个T(70)LV, 这个V里面是由很多条T(61)LV,  终端要注意处理这种嵌套结构这个T(61)LVV(也就是入口)可能是ADF,也可能是DDF. 如下图: 

注意上面两图格式中的TAG顺序可以不是固定的. 比如说,在第二个图中,tag ‘4F’可以出现在’50’之后等等我以前一直以为这个顺序是固定的直到2012.12.1 EMV l2的案例升级,新增了一条案例专门测试这一点,才知道这个顺序是可以变的.  

如果入口是ADF,那就简单了,直接取4F的值就可以了然后索引指向下一条难点在于如果是DDF,那终端选择这个DDF,然后取FCI中的SFI,然后读这个SFI中的记录说到这里大家应该已经看出来了,入口是DDF的情况相当于又回到了步骤1, 只是把选择PSE变为选择DDF.

这种情况下,就需要保存进入DDF处理前的断点信息,以便处理完这个DDF后,可以继续当前的处理过程这个有点像CPU中的嵌套中断它的原理是利用堆栈来保存断点处的信息处理完中断就恢复堆栈.  这个处理过程中体现的程序上一般是有两种处理方法一是递归, 二是非递归递归的方法处理起简单,易读,但是效率比较低不过EMV的测试案例中的记录格式一般都比较简单,嵌套的不深下面给出伪代码的流程,假设建立列表的函数名为BuildListByDDF


点击(此处)折叠或打开

  1. BuildListByDDF(char *DDF)
  2. {
  3.     选择PSE(DDF);
  4.     读取SFI
  5.     While(读SFI中的记录不返回6A83)
  6.     {
  7.       If(取tag70成功)
  8.       {
  9.           If(取tag61成功)
  10.          {
  11.              If(取到的入口是4F )
  12.             {
  13.                 对比终端AID,如果一致(部分匹配或完全匹配),就加入候选列表;
  14.             }
  15.            else If(取到的入口是9D)
  16.             {
  17.                    BuildListByDDF(9D的DDF值);//注意这里递归
  18.                      标志位置位;
  19.             }
  20.       }
  21.   }
  22.     If(标志位置位) /*标志位的作用是为了重新选择卡片,使卡片再被递归中的选择后, 恢复的到当前的状态*/
  23.    {
  24.       重新选择当前的DDF,并读到SFI
  25.    }
  26.  }
  27. }

经过第二步之后候选列表基本建立起来了最后一步是根据AID的优先级参数进行排序一般我们会用一个数组变量保存应用列表可以让优先级最高的应用放在数组的最开始位置这样便于在不支持持卡人确认时,自动选择优先级最高的应用.

阅读(2518) | 评论(0) | 转发(3) |
给主人留下些什么吧!~~