simCard 学习总结

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

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

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

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

1 Sim卡信息的初始化:

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解锁失败永久锁定。

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

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

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

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

UiccCardApplication去读取SIM卡里的信息。同时还创建了CatService用于读取STK的信息。

7:在处理caseEVENT_GET_ICC_STATUS_DONE_FOR_SIM_MISSING

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

DcTrackerBasePhoneBaseGsmSMSDispatcherIccCardProxyServiceStateTracker,CatService

 

2 UiccCardApplication处理SIM卡状态:

UiccCardApplicationupdate()方法流程图


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

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卡中的信息。

流程图如下:

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卡信息初始化相关类的关系及说明

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卡信息处理过程

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相关方法进行处理,

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

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

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


<think>好的,我现在需要帮助用户解决关于Dify循环实现的问题。首先,我需要明确用户的具体需求。他们提到“dify 循环实现”或“dify 如何处理循环”,但Dify本身可能没有直接称为“循环”的功能,所以需要结合现有文档中的信息来推断可能的解决方案。 根据用户提供的引用内容,Dify工作流中有迭代节点[^1]。这可能类似于编程中的循环结构,用于重复执行某个任务。例如,在处理列表数据或需要多次执行同一操作时,迭代节点可以派上用场。我需要详细解释迭代节点的配置和使用步骤,确保用户能够理解如何设置循环次数或遍历数据集。 另外,用户可能对如何处理循环中的错误或性能问题感兴趣。引用[2]提到在Dify中处理PEM文件的问题,这可能涉及在循环中正确处理数据格式,避免错误积累。需要提醒用户在循环中注意错误处理和资源管理,确保每次迭代的稳定性。 引用[3]中的例子展示了如何结合FastAPI和Selenium进行实时监控并生成GIF,这可能涉及循环截取浏览器内容。虽然Dify本身可能不直接控制这类循环,但可以通过外部脚本或定时任务触发工作流,模拟循环执行。这部分需要说明如何将外部循环机制与Dify结合使用。 接下来,我需要组织回答结构。首先介绍迭代节点的基本概念和配置步骤,然后讨论循环中的数据处理和错误处理,最后补充外部触发循环的方法。同时,生成相关问题以帮助用户进一步探索,比如优化循环性能或处理复杂数据结构。 需要确保回答符合格式要求,使用正确的中文表达,行内公式用$...$,独立公式用$$...$$,但当前问题不涉及数学公式,所以可能不需要使用。同时,引用标识要自然地添加到相关段落末尾,如、[^2]、[^3]。 最后,检查是否有遗漏点,比如Dify的其他循环相关功能或用户可能遇到的常见问题,确保回答全面且易于理解。</think>在Dify中处理循环逻辑主要通过**迭代节点**实现,以下是具体实现方式和应用场景的解析: ### 一、Dify循环实现机制 Dify通过**工作流设计器**中的迭代节点处理循环需求,其核心原理类似编程中的`for循环`。迭代节点可遍历以下数据类型: - 数组列表:`["A","B","C"]` - 字典集合:`{"key1":"value1", "key2":"value2"}` - 数值范围:通过`range()`函数生成序列 配置示例: ```python # 模拟迭代节点的数据输入 input_data = { "dataset": [1,2,3,4,5], "process_logic": "item * 2" # 对每个元素执行乘以2的操作 } ``` ### 二、迭代节点的关键配置步骤 1. **数据源绑定**:将数组/字典类型变量连接到迭代节点的输入端口 2. **循环变量命名**:设定当前元素的变量名(默认为`item`) 3. **子流程设计**:在迭代节点内部构建需要重复执行的逻辑模块 4. **结果聚合**:通过`outputs`收集所有迭代结果,支持数组或对象格式 $$ \text{总耗时} = \sum_{i=1}^{n}(单次迭代时间_i) + 系统开销 $$ ### 三、循环中的特殊处理 1. **错误中断控制**: - 启用`continueOnError`参数可跳过失败迭代 - 通过`try-catch`模块包裹敏感操作 2. **并行优化**: ```python # 伪代码示例 Parallel.forEach(dataset, lambda item: process(item)) ``` 3. **结果过滤**: ```python filtered = filter(lambda x: x%2==0, processed_results) ``` ### 四、应用场景案例 1. **批量文件处理**:遍历存储桶中的文件列表进行格式转换 2. **数据清洗**:对数据库查询结果集进行逐条校验 3. **API轮询**:定时循环调用第三方接口直到满足特定条件
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值