目的:
如本节所述,终端需要取得IC卡的文件中包含的数据,用以完成交易中的各种功能。终端必须从 IC卡读取这些数据。
终端使用读记录命令(READ RECORD)读出在应用文件定位器中标记的文件与记录,并在读记录命令中使用SFI来标记文件。
AFL是标记在交易中使用的文件及记录的一个列表。终端仅读取在AFL中标记的记录。表的每个元素对应一个可以读出的文件,并且按照如下规则组织:
l 第一字节的高5位定义了SFI,低3位为0。
l 第二字节定义了此SFI中可以被读出的第一条(或唯一的)记录的序号。第二字节不能为0。
l 第三字节定义了此SFI中可以被读出的最后一条记录的序号。它的值大于或等于第二字节的值。当第三字节比第二字节大时,SFI中序号范围从第二字节到第三字节(包括)的所有记录都可以读出。当第三字节与第二字节相等时,只有SFI中序号为第二字节值的记录可以读出。
l 第四字节定义了从第二字节的记录序号开始的脱机数据认证相关的记录数。第四字节的范围可以从零到第三字节的值减去第二字节的值再加1。
终端应该按照从左至右的顺序处理AFL中的条目。
- /**
- * 功 能:读应用数据
- * 读数据. 命令是read record. 参数是前一步得到的终端所需卡片数据的位置和名称.
- * 终端要把AFL指定的所有数据读出,并保存到终端供下面的流程所用.
- * 每次读到的数据是包含在卡片的返回信息中的, 终端解析返回信息,提取相关的数据.
- * 入口参数:
- * 出口参数:
- * 返回值:
- * 开发人员:Lzy 2012-12-12
- * 修改记录:
- */
- int PbocReadAppData(char *GPO)
- {
- unsigned char sCmd[10], *gpo = GPO, recvlen = 0;
- char k, i, j, p1, p2;
- int ret, len;
- unsigned char recvbuf[255];
- /**
- * AFL(应用文件定位器),每个AFL包括4个字节字节
- * 1:bit8-bit4:SFI(短文件标识符) bit3-bit1:000
- * 字节2:文件中要读的第1个记录的记录号(不能为0)
- * 字节3:文件中要读的最后一个记录的记录号(大于或等于字节2)
- * 字节4:从字节2的记录好开始,用于静态数据记录的个数(从0开始,不大于(字节3)-(字节2)+1)
- */
- len = *(GPO + 1) - 2; /* 得到ALF长度*/
- for (k = 0; k < len / 4; k++) /* 第K个ALF*/
- {
- gpo += 4;
- for (i = gpo[1]; i <= gpo[2]; i++) /* 读取一个AFL应用文件 */
- {
- bzero(sCmd, sizeof(sCmd));
- bzero(recvbuf, sizeof(recvbuf));
- pr_debug("\n[%d][%d]ALF:[%02X] [%02X] [%02X] [%02X] \n",k+1,i, gpo[0],gpo[1],gpo[2],gpo[3]);
- p1 = i; /* 记录号*/
- p2 = gpo[0] | 0x04; /* SFI */
- sprintf(sCmd, "%c%c%c%c%c", 0x00, 0xB2, p1, p2, 255);
- ret = SendCmd(sCmd, 5, recvbuf, &recvlen);
- if (recvbuf[0] == 0x6C || recvbuf[0] == 0x61)
- {
- sprintf(sCmd, "%c%c%c%c%c", 0x00, 0xB2, p1, p2, recvbuf[1] & 0XFF);
- ret = SendCmd(sCmd, 5, recvbuf, &recvlen);
- }
- if (ret != 0)
- pr_err("ReadRecord error\n");
- for (j = 0; j < recvlen; j++)
- pr_debug("%02X ", recvbuf[j]);
- pr_debug("\n");
- }
- }
- }
PBOC2.0.tar.zip
阅读(351) | 评论(0) | 转发(0) |