simCard 学习总结

本文主要介绍了三大内容:

1SIM卡准备就绪后信息的读取;

2UiccCard主要相关类的架构和功能介绍

3:以SIM卡中联系人信息的读取详述SIM信息读取过程。

1 Sim卡信息的初始化:

simCard 学习总结_第1张图片

1:一个主动上报到消息,在processUnsolicited()方法中对消息处理后直接通知给UiccController

2:UiccController收到通知后会继续获取sim卡中变化的状态信息

3:调用RIL中的方法获取sim卡中变化的状态信息,同时注册了对返回消息的处理

4RIL中下发request获取sim卡的状态信息

5:对获取到的sim卡信息进行读取和封装:在responseIccCardStatus(Parcel p)方法中对下层上报的Parcel进行读取,根据读出的值对cardstatepinstate的状态,卡中application的类型,状态进行赋值,最终返回IccCardStatus对象值。

其中cardstate有三种状态:

CARDSTATE_ABSENT//掉卡

CARDSTATE_PRESENT//正常

CARDSTATE_ERROR//错误

pinstate有六种状态:pin码未知,pin锁定输入pin错误无法进入手机,pin锁定输入pin正确进入手机,没有进行pin锁定,pin解锁失败输入pukpuk解锁失败永久锁定。

simCard 学习总结_第2张图片

接着对返回的IccCardStatus对象值进行封装:AsyncResult.forMessage(rr.mResult,ret, null);

6:把封装好的值发给目标Handler,即:UiccController

7&8:UiccController中使用IccCardStatus的值创建或更新UiccCard

simCard 学习总结_第3张图片

9:UiccCard中根据获取的SIM卡信息创建或更新UiccCardApplication,一直用到了IccCardStatus对象作为参数,在创建UiccCardApplication对象时用到IccCardStatusIccCardApplicationStatus属性值,包括SIM卡中应用类型,应用状态。

UiccCardApplication去读取SIM卡里的信息。同时还创建了CatService用于读取STK的信息。simCard 学习总结_第4张图片

7:在处理caseEVENT_GET_ICC_STATUS_DONE_FOR_SIM_MISSING

onGetIccCardStatusDone(...)方法中最后通知注册者sim卡状态发生了变化。其中注册者有:

DcTrackerBasePhoneBaseGsmSMSDispatcherIccCardProxyServiceStateTracker,CatService

 

2 UiccCardApplication处理SIM卡状态:

UiccCardApplicationupdate()方法流程图

simCard 学习总结_第5张图片


1&2:在UiccCardApplication中分别创建了IccFileHandler,IccRecords对象,实际上是根据卡中应用的类型分别创建了具体的信息读取者SIMFileHandler和信息记录者SIMRecords,从传入的参数可以看出这一点(参数为:as.app_type

simCard 学习总结_第6张图片

3:queryFdn();//查询定拨号信息

  queryPin1State();//PIN查询

如果需要pin解锁则会发出解锁通知进行解锁,然后发生状态变化继续更新UiccCardUiccCardApplication直到ready;接着会发出Uicc ready通知。

创建SIMRecords对象时,其构造方法中实现了电话本的缓存和SIM卡重要信息的读取,如下:

public SIMRecords(UiccCardApplication app, Context c, CommandsInterfaceci) {
    super(app,c, ci);
    // 1.电话本的缓存
    mAdnCache = new AdnRecordCache(mFh);
   
     mVmConfig =new VoiceMailConstants();
    mSpnOverride = new SpnOverride();
   
   mRecordsRequested = false; // No load request ismade till SIM ready

// recordsToLoad is set to 0 because no requests aremade yet
    mRecordsToLoad= 0;
   
    mCi.setOnSmsOnSim(this, EVENT_SMS_ON_SIM, null);
    mCi.registerForIccRefresh(this, EVENT_SIM_REFRESH,null);
   
    // Start off by setting empty state
    resetRecords();
    //2. 读取 SIM卡的所有重要的记录信息
    mParentApp.registerForReady(this, EVENT_APP_READY,null);
    if (DBG) log("SIMRecords X ctor this=" +this);
    }

1:创建AdnRecordCache,用于保存电话本数据,根据EFID,可以分别读取SIM卡和USIM卡的电话本数据。AdnRecordCache 中有一个UsimPhoneBookManager,用来读取USIM卡电话本数据。

2:注册监听mParentApp.registerForReady(this,EVENT_APP_READY, null);其实是在UiccCardApplication中进行监听,至此所有的准备工作已完成,就等SIM卡就绪后则主动读取SIM卡中重要信息,如:ICCIDSIMid),IMSI(国际移动用户识别码),SMS(短消息)等

ICCID:集成电路卡识别码,IC卡的唯一识别码,共20位,移动898600898602,联通为898601,电信为898603,不同运营商发行的SIM卡编码规则不同;


3:首先读取就是IMSImCi.getIMSIForApp(mParentApp.getAid(),obtainMessage

(EVENT_GET_IMSI_DONE));详细介绍下IMSI

IMSI是国际移动用户识别码的简称(International Mobile Subscriber Identity)共有15位,其结构如下:

MCC+MNC+MSIN

MCCMobileCountry Code,移动国家码,共3位,中国为460;

MNC:Mobile NetworkCode,移动网络码,共2位在中国,移动的代码为电0002,联通的代码为01,电信的代码为03;合起来就是(也是Android手机中APN配置文件中的代码):

中国移动:46000 46002

中国联通:46001

中国电信:46003

MSIN:Mobile Subscriber Identification Number,移动用户识别号码,共10位,

一个典型的IMSI号码为460030912121001


3 IccFileHandler读取SIM卡信息

SIMRecords的构造方法中注册了对EVENT_APP_READY的监听,当SIM卡准备就绪时,SIMRecords会处理EVENT_APP_READY事件,接着会读取SIM卡中的信息。

流程图如下:

simCard 学习总结_第7张图片

1:在SIMRecords.java的构造方法中注册对EVENT_APP_READY的监听,同时还注册了对RADIOSMS等监听.

2:当simAppStatePinState就绪后通知SIMRecords.java,

3&4&5&6:SIMRecords.java中处理caseEVENT_APP_READY,fetchSimRecords()中会分别调用IccFileHandler.javaloadEFLinearFixed(int fileid, int recordNum, Message onLoaded)loadEFTransparent(int fileid, Message onLoaded)方法;这两个方法的区别在于:前者读取线性文件,读取信息有电话本,短信等;后者读取透明文件,读取卡的一些基本信息,如IMSI。方法中的参数fileid就是用来获取不同字段数据的。

7:在IccFileHandler.java中最终会调用RIL.javaiccIOForApp (int command, intfileid, String path, int p1, int p2, int p3, String data, String pin2,String aid, Message result)方法。对该方法的参数解释如下:

command:读,写,更新的操作指令

fileid:数据字段在SIM文件中的地址,如EF_ICCID0x2fe2

path:数据字段上级所有目录地址:如PlmnpathMF+DF_GSM,UICC文件结构和地址决定

p1,p2,p3,data,pin2,aid:由UICC传递上来,其中p1p2p3可在3GPP协议中查看

result:回调Message.

该方法下发RIL_REQUEST_SIM_IO指令读取SIM卡内信息。

8&9:对上报的消息进行处理,在responseICC_IO(Parcel p)将上报的数据封装成IccIoResult对象,发送给目标IccFileHandler.java

10&11&12&13&14:

IccFileHandler.java中处理caseEVENT_GET_RECORD_SIZE_DONE接着会继续调用到RIL.javaiccIOForAppEx(intcommand, int fileid, String path, int p1, int p2, int p3, String data, String pin2, String aid, int channel , Message result)方法,下发RIL_REQUEST_SIM_IO_EX指令,将上报的解决再次发给目标IccFileHandler.java

15&16&17:IccFileHandler.java处理:case:EVENT_READ_RECORD_DONE的过程中会判断信息是否被完全读取,如果没有则会一直重复步骤11,直到完成信息读取。信息读取完成后会调用自身sendResult(Message response, Object result, Throwable ex)方法,把消息发给监听者处理。

4 SIM卡信息初始化相关类的关系及说明

simCard 学习总结_第8张图片

UiccController:整个Uicc相关信息的控制接口,监控SIM状态变化

UiccCard:Uicc卡的抽象,用来更新卡的状态

IccCardStatus:维护Uicc卡的状态,CardState&PinState

UiccCardApplication:Uicc的一个具体的应用,负责卡中数据读写,存取,pinpuk密码设置,解锁

CatService:主要负责SIM Tollkit相关

IccConstants:SIM卡中文件地址,不同数据在SIM卡上的字段地址。

IccRecords:记录SIM卡的数据

IccFileHandler:读取SIM卡数据以及处理接收的结果。

5 以sim卡中联系人读取为例详述sim卡信息处理过程

simCard 学习总结_第9张图片

1:SIM卡中联系人是自动导入的,在Contact中注册了android.intent.action.BOOT_

COMPLETED,收到开机完成的广播后Contact会开起内部的服务SIMProcessorService进一步在SIMImportProcessorquerySIMContact(...)中访问SIM卡数据库,通过Uri匹配可知会访问到IccProvider这个类的Query方法。

2:在loadFromEf(int efType, int simId)efType是根据Uri匹配得到的ADN/FDN

/SDN/PBR;其中ADN即常规的用户存储的号码,FDN是固定拨号,开启此功能后只能拨打固定号码列表内的号码,SDN是系统拨号,网络服务拨号,固化在SIM卡中。

3&4:根据simId获取电话薄管理,其实获取的是一个

IccPhoneBookInterfaceManagerProxy对象。

5-9:每个方法根据参数efType来逐个调用,同时注册了callback,步骤8加锁

waitForResult(status);步骤9:这里会根据efid的不同去读取SIM卡与USIM卡中存储联系人信息,SIM卡为:IccConstants.EF_ADN,USIM卡为: IccConstants.EF_PBR

10:首先读取的是IccConstants.EF_FDN然后会读取IccConstants.EF_PBR,最后会读取

IccConstants.EF_SDN

11-13:循环调用RILIccIOForApp的方法读取SIM卡中号码直到读完。首先会读取联系人记录的总数,再读取第一个联系人的记录,保存读取到的内容,然后读取下一条记录,以此类推...

读取到的IccConstants.EF_FDN如下:

IccConstants.EF_PBR

IccConstants.EF_SDN:

 

14-19:利用callback将读取的信息返回给上一级进行处理。在                                     

20-22:处理case:EVENT_LOAD_DONE时调用 notifyPending(ar); 8:进行解锁,

AdnRecord对象依次传递给上一级。

23:执行完loadFromEf(efType, simId)方法后,将返回的读取结果转换成cursor对象返回,以上流程同样适用与USIM卡内联系人的读取,读取USIM卡联系人,Email信息时会在步骤8调用到UsimPhoneBookManager相关方法进行处理,

simCard 学习总结_第10张图片

UsimPhoneBookManager中可以看到进行判断处理后会继续调用AdnRecordCache对象方法或者直接调用IccFileHandler对象进行信息读取

simCard 学习总结_第11张图片

USIM卡与SIM卡的区别主要体现在:

USIM卡是SIM卡的升级,安全性更高,卡机接口速率更高,存储功能更强大,支持更多的逻辑应用,一般USIM卡包括USIMSIM两个逻辑块,即兼容2G3G终端,内置文件类型多于SIM卡。


你可能感兴趣的:(android,开发)