读取SIM卡中的EF文件流程

介绍读取SIM卡中的EF文件的流程。
部分内容参考如下文档:https://onlinesso.mediatek.com/Pages/FAQ.aspx?List=SW&FAQID=FAQ08976

以读取EF_SPN文件为例
先看下spec中对这个栏位的描述(3GPP TS 51.011):
这里写图片描述
这里写图片描述

文件ID是6F46,属于Optional类型,所以SIM卡可以不支持此文件
文件类型是transparent(不同文件类型的读取方法有差异)
文件大小为17个字节,其中第一个字节代表Display Condition,剩下的字节就是SPN信息了。

  1. 首先用超级终端模拟读取EF_SPN
    // 1.获取文件大小
    AT+CRSM=192,28486,0,0,15

+CRSM: 0, 0
OK

// 2. 根据之前拿到的文件大小读取文件
AT+CRSM=176,28486,0,0,17

+CRSM: 0, 0
OK

如果你能够从spec中确认文件长度是17的话,第一步也可以省略,但是Android代码中在读文件之前都会先获取文件大小的。

2.再看看相关spec中的描述
(3GPP TS 11.11)
这里写图片描述

这里写图片描述

从这里我们能了解到的是:
COMMAND_READ_BINARY = 0xb0
也就是READ BINARY对应的命令是176
COMMAND_GET_RESPONSE = 0xc0
GET RESPONSE对应的命令是192

  1. 结合代码看流程
    SIMRecords.java
// call loadEFTransparent to load EF_SPN
mFh.loadEFTransparent(EF_SPN,
                        obtainMessage(EVENT_GET_SPN_DONE));
// now we get the EF_SPN                        
case EVENT_GET_SPN_DONE:
    ar = (AsyncResult) msg.obj;
    data = (byte[]) ar.result;
    // get the first byte
    mSpnDisplayCondition = 0xff & data[0];
    // get other bytes which is service provider name
setServiceProviderName(IccUtils.adnStringFieldToString(data, 1, data.length - 1));

这里并没有看到需要两次at命令读取EF文件,要了解细节还要继续看loadEFTransparent的实现

public void loadEFTransparent(int fileid, Message onLoaded) {
    Message response = obtainMessage(EVENT_GET_BINARY_SIZE_DONE,
                    fileid, 0, onLoaded);
    mCi.iccIOForApp(COMMAND_GET_RESPONSE, fileid, getEFPath(fileid),
                    0, 0, GET_RESPONSE_EF_SIZE_BYTES, null, null, mAid, response);
}

这里可以看到,原来处理loadEFTransparent返回事件的Message(EVENT_GET_SPN_DONE)已经被封装到新的Message的obj变量中,而真正的what已经被替换为EVENT_GET_BINARY_SIZE_DONE,所以当iccIOForApp(COMMAND_GET_RESPONSE)这个call返回后处理的事件是EVENT_GET_BINARY_SIZE_DONE.
也请留意:
command是COMMAND_GET_RESPONSE,即192(0xc0)
p1=0, p2 = 0, p3 = GET_RESPONSE_EF_SIZE_BYTES = 15
对应超级终端命令中的:AT+CRSM=192,28486,0,0,15
28486当然是0x6F46啦

case EVENT_GET_BINARY_SIZE_DONE:
    ar = (AsyncResult)msg.obj;
    response = (Message) ar.userObj;
    result = (IccIoResult) ar.result;

    data = result.payload;
    fileid = msg.arg1;
    channel = msg.arg2;

    size = ((data[RESPONSE_DATA_FILE_SIZE_1] & 0xff) << 8)
           + (data[RESPONSE_DATA_FILE_SIZE_2] & 0xff);
    mCi.iccIOForAppEx(COMMAND_READ_BINARY, fileid, getEFPath(fileid),
                    0, 0, size, null, null, mAid, channel,
                    obtainMessage(EVENT_READ_BINARY_DONE,
                                  fileid, 0, response));

新的接受response的Message已经从ar.userObj中提取出来啦,就是最初的EVENT_GET_SPN_DONE。
COMMAND_GET_RESPONSE会返回EF文件的大小,存储在data中的第三和第四个字节中,这里应该是17.
新的command已经变成了COMMAND_READ_BINARY,也就是176
这就是读取EF文件的两个步骤。

  1. 下面看下log信息
// 第一次调用iccIOForApp读取EF文件大小
09-19 14:24:26.369 D/RILJ    ( 2242): [3949]> iccIO: SIM_IO 0xc0 0x6f46  path: 3F007FFF,0,0,15 aid: null [SUB0]
09-19 14:24:26.377 D/RIL     (  755): requestSimIo 192, 28486, 3F007FFF, 0, 0, 15 !!
09-19 14:24:26.377 D/RIL     (  755): GET RESPONSE on USIM 3F007FFF:6f46, p3:15
09-19 14:24:26.377 D/RIL     (  755): usimGetResponse, path: 3F007FFF
09-19 14:24:26.377 D/AT      (  755): AT> AT+CRSM=192,28486,0,0,0,,"7FFF"
09-19 14:24:26.377 D/AT      (  755): AT+CRSM=192,28486,0,0,0,,"7FFF"

09-19 14:24:26.402 I/AT      (  755): AT read end: 75:Success
09-19 14:24:26.402 D/AT      (  755): +CRSM: 144, 0, "62168202412183026F468A01058B036F0607800200118800"
09-19 14:24:26.402 D/AT      (  755): 
09-19 14:24:26.402 D/AT      (  755): OK

09-19 14:24:26.403 D/RIL     (  755): makeSimRspFromUsimFcp, format_wrong: 0
// 请注意这里,代码中针对USIM的get response命令似乎有特殊的处理,所以这里的数据才是真正返回的数据,而它的第三和第四个字节则对应EF文件的大小:0011,转为十进制就是17
09-19 14:24:26.403 D/RIL     (  755): simRsp done:000000110000040000000000000000
// 至此,第一次条用处理完毕
09-19 14:24:26.403 D/RILJ    ( 2242): [3949]< SIM_IO IccIoResponse sw1:0x90 sw2:0x0 [SUB0]

//下面开始根据文件大小读取文件中的信息
09-19 14:24:26.410 D/RILJ    ( 2242): [3950]> iccIO: SIM_IO_EX 0xb0 0x6f46  path: 3F007FFF,0,0,17,channel:0 aid: null [SUB0]
//下发 at command
09-19 14:24:26.416 D/AT      (  755): AT> AT+CRSM=176,28486,0,0,17,,"7FFF"
09-19 14:24:26.416 D/AT      (  755): AT+CRSM=176,28486,0,0,17,,"7FFF"
//碰巧我这张SIM卡中没有SPN信息
09-19 14:24:26.451 D/AT      (  755): +CRSM: 144, 0, "00FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
//至此,第二次条用处理完毕
09-19 14:24:26.452 D/RILJ    ( 2242): [3950]< SIM_IO_EX IccIoResponse sw1:0x90 sw2:0x0 [SUB0]

//最后是调用这SIMRecords处理返回信息:spn信息为空字符串
09-19 14:24:26.455 D/SIMRecords( 2242): [SIMRecords] EF_SPN loaded and try to extract:  (slot 0)
09-19 14:24:26.455 D/SIMRecords( 2242): [SIMRecords] getSpnFsm, Got data from EF_SPN (slot 0)
09-19 14:24:26.455 D/SIMRecords( 2242): [SIMRecords] setServiceProviderName: spn= (slot 0)
09-19 14:23:53.760 D/SIMRecords( 2242): [SIMRecords] set spNameInEfSpn to null because parsing result is empty (slot 0)
//spnDisplayCondition为0,但因为spn为空,所以这个值是多少也无关紧要啦。
09-19 14:23:53.760 D/SIMRecords( 2242): [SIMRecords] Load EF_SPN:  spnDisplayCondition: 0 (slot 0)

注:代码和log信息参考MT6752平台,Android 5.1

  • 1
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值