目录

前言

一、问题现象

二、分析过程

1、排查modem状态

2、确定第一次异常时刻

3、分析运营商信息更新流程

4、定位运营商信息更新失败原因

5、定位再次热插拔无法恢复的原因

三、解决方案


前言

1、文章由移远通信技术股份有限公司提供。

2、以下内容包含了个人理解,仅供参考,如有不合理处,请联系笔者修改/删除,18674066883(微信同号)。

一、问题现象

    反复热插拔SIM卡,有概率(出现概率1/30)出现状态栏显示“No Service”,也ping不通网络,继续热拔插卡无法恢复,只能重启恢复。

二、分析过程

1、排查modem状态

     出现不识卡问题,首先需要判断是底层modem问题还是系统自身原因导致不识卡,根据日志打印,CPIN查询结果为ready,C5GREG都返回正常,说明modem已驻网

2、确定第一次异常时刻

    问题现象是在某次不识卡后再次热拔插卡也不识卡,所以可以大致确定是在第一次出现异常时影响了后续的识卡流程。这里定位第一次异常点是直接通过运营商信息的更新过程来确定,每次拔卡后,运营商信息从“中国联通”变为“Emergency calls only”,插卡时相反,所以第一次出现curPlmn与plmn都是“Emergency calls only”时,即是第一次异常时刻。

3、分析运营商信息更新流程

    根据日志走读代码可以确定运营商名称是通过RadioRilOperator获取,RadioRilOperator接收的是底层上报事件(事件ID: 304)

4、定位运营商信息更新失败原因

    上一步了解了运营商信息更新流程,据此排查,可以定位到运营商信息更新失败是RadioRilOperator接收到的信息为空所致。

    进一步分析底层上报事件的过程,再结合日志,可以确定,在异常时,RIL返回给上层的结果中,errorCode字段是非NONE,所以没有把RIL返回的运营商信息(getDataFunc)上报,而是返回了RadioResponseInfo类型的结果。

但是上层RadioRilOperator接口所判空的数据类型是OperatorInfoResult,所以当RIL返回结果的error code字段非NONE时就会导致RIL返回给上层的OperatorInfoResult数据丢失,改为上报RadioResponseInfo数据,从而使运营商信息更新失败。

5、定位再次热插拔无法恢复的原因

    梳理发起获取运营商信息请求到接收运营商信息上报结果,发起获取运营商信息请求的接口是RadioOnState,在日志中可以找到859行的打印“Last request not finish”,对比正常和异常两种场景,虽然都会打印该字段,但是正常情况下不会一直打印该字段,而异常场景时会一直打印,GetRilOperatorInfo、GetRilPsRegistration和GetRilCsRegistration也没有再被调用。据此可以确定,857行的条件阻塞了后续的流程。forceNotify显然不是问题原因,接下来分析networkSearchManager->CheckIsNeedNotify(slotId_)为什么会一直为false。

networkSearchManager->CheckIsNeedNotify(slotId_)检查的是计数器msgNum_,只有msgNum_等于0时才返回true。计数器初始化时其值为3(MSG_NUM),每调用一次decMsgNum,计数器减1。

计数器msgNum_只有在RadioOnState接口中被初始化

计数器msgNum_减1的操作分别在RadioRilDataRegState、RadioRilVoiceRegState和RadioRilOperator中完成

由于异常时RadioRilOperator接口在695行返回,698行的decMsgNum没有被执行,所以计数器msgNum_一直处于非0状态,导致RadioOnState无法再继续发起请求,再次热插拔SIM卡也无法恢复,只能重启设备。

三、解决方案

    注:请求结果中error code为非0的问题这里不做深入探讨,仅解决上层代码的健壮性问题。

    在RadioRilDataRegState、RadioRilVoiceRegState和RadioRilOperator增加RadioResponseInfo类型数据的判断,当目标类型数据为空时继续判断RadioResponseInfo类型数据,如果RadioResponseInfo类型数据非空则执行计数器msgNum_减1操作,避免出现一直阻塞的问题

patch如下:

diff --git a/services/network_search/src/network_search_handler.cpp b/services/network_search/src/network_search_handler.cpp
index 3cfffde1..480363f5 100644
--- a/services/network_search/src/network_search_handler.cpp
+++ b/services/network_search/src/network_search_handler.cpp
@@ -611,6 +611,10 @@ void NetworkSearchHandler::RadioRilDataRegState(const AppExecFwk::InnerEvent::Po
     std::lock_guard<std::mutex> lock(mutex_);
     psRegStatusResultInfo_ = event->GetSharedObject<PsRegStatusResultInfo>();
     if (psRegStatusResultInfo_ == nullptr) {
+        auto info = event->GetSharedObject<RadioResponseInfo>();
+        if ((info != nullptr) && (info->flag == networkSearchManager->GetSerialNum(slotId_))) {
+            networkSearchManager->decMsgNum(slotId_);
+        }
         TELEPHONY_LOGE("psRegStatusResult is nullptr slotId:%{public}d", slotId_);
         return;
     }
@@ -642,6 +646,10 @@ void NetworkSearchHandler::RadioRilVoiceRegState(const AppExecFwk::InnerEvent::P
     std::lock_guard<std::mutex> lock(mutex_);
     csRegStatusInfo_ = event->GetSharedObject<CsRegStatusInfo>();
     if (csRegStatusInfo_ == nullptr) {
+        auto info = event->GetSharedObject<RadioResponseInfo>();
+        if ((info != nullptr) && (info->flag == networkSearchManager->GetSerialNum(slotId_))) {
+            networkSearchManager->decMsgNum(slotId_);
+        }
         TELEPHONY_LOGE("csRegStatusResult is nullptr slotId:%{public}d", slotId_);
         return;
     }
@@ -691,6 +699,10 @@ void NetworkSearchHandler::RadioRilOperator(const AppExecFwk::InnerEvent::Pointe
     std::lock_guard<std::mutex> lock(mutex_);
     operatorInfoResult_ = event->GetSharedObject<OperatorInfoResult>();
     if (operatorInfoResult_ == nullptr) {
+        auto info = event->GetSharedObject<RadioResponseInfo>();
+        if ((info != nullptr) && (info->flag == networkSearchManager->GetSerialNum(slotId_))) {
+            networkSearchManager->decMsgNum(slotId_);
+        }
         TELEPHONY_LOGE("operatorInfoResult is nullptr slotId:%{public}d", slotId_);
         return;
     }

修复代码已提交至社区:

https://gitcode.com/openharmony/telephony_core_service/pull/3440

Logo

社区规范:仅讨论OpenHarmony相关问题。

更多推荐