Android RIL 调试问题分析 ——数据频繁断开

Android RIL 调试问题分析 ——数据频繁断开

  • 1. 问题描述
  • 2. 问题分析
    • 2.1 RIL初分析
    • 2.2 数据业务重试机制梳理和分析
    • 2.3 网卡统计数据的分析

1. 问题描述

在使用SDX55模组和对应支持NSA/SA网络的RIL时,出现数据业务频繁断开重连现象,用户体验较差。

2. 问题分析

2.1 RIL初分析

从ril log中初步分析,可以得到数据频繁断开原因均一致,原因见以下log段:

07-31 15:06:42.594 D/DCT     ( 1617): [0]Data stall alarm
07-31 15:06:42.594 D/DCT     ( 1617): [0]onActionIntentDataStallAlarm: action=com.android.internal.telephony.data-stall
07-31 15:06:42.596 D/DCT     ( 1617): [0]updateDataStallInfo: mDataStallTxRxSum={
   txSum=0 rxSum=0} preTxRxSum={
   txSum=0 rxSum=0}
07-31 15:06:42.596 D/DCT     ( 1617): [0]updateDataStallInfo: NO IN/OUT
07-31 15:06:42.597 D/DCT     ( 1617): [0]getRecoveryAction: 1
07-31 15:06:42.597 D/DCT     ( 1617): [0]onDataStallAlarm: tag=14890 do recovery action=1
07-31 15:06:42.597 D/DCT     ( 1617): [0]getRecoveryAction: 1

这段log中分析出数据断开是安卓上层的数据恢复机制导致断开重连,但是由于什么原因导致的断开重连还需要我们去深入了解下这个机制的原理和触发条件,才能进一步分析解决问题。

2.2 数据业务重试机制梳理和分析

Framework telephony中数据业务链接错误处理一般分3种情况:

  1. SETUP_DATA_CALL 时返回错误
  2. Modem上报DATA_CALL_LIST包含错误码或者链接中断
  3. 一段时间内没有上下行数据(TX/RX)

下面具体来看每种情况的处理。

  • 1、SETUP_DATA_CALL失败
    DataConnection在收到SETUP_DATA_CALL结果后,用Message通知DcTracker处理:
protected void onDataSetupComplete(AsyncResult ar) {
   
    if (ar.exception == null) {
   //链接成功
}
else{
   
        ...
        //标记permanent fail的次数,会影响后面onDataSetupCompleteError的判断
        if (isPermanentFail(cause)) apnContext.decWaitingApnsPermFailCount(); 
        apnContext.removeWaitingApn(apnContext.getApnSetting()); //从waiting列表中移除已经失败的APN
        onDataSetupCompleteError(ar);//继续处理错误
        ...
    }
}

处理Error的逻辑:

  • 如果apnContext中的所有waiting APN都失败了,且不是每个都发生permanent fail(永久性错误),则设置delay并重新发起这次连接
  • 如果apnContext中仍有没有尝试的waiting APN,则设置delay并尝试用下一个APN去连接
/**
     * Error has occurred during the SETUP {aka bringUP} request and the DCT
     * should either try the next waiting APN or start over from the
     * beginning if the list is empty. Between each SETUP request there will
     * be a delay defined by {@link #getApnDelay()}.
     */
    @Override
    protected void onDataSetupCompleteError(AsyncResult ar) {
   
        String reason = "";
        ApnContext apnContext = getValidApnContext(ar, "onDataSetupCompleteError");
        if (apnContext == null) return;
        //已经尝试过所有APN
        if (apnContext.getWaitingApns().isEmpty()) {
   
            apnContext.setState(DctConstants.State.FAILED);//apnContext state设置成FAILED
            mPhone.notifyDataConnection(Phone.REASON_APN_FAILED, apnContext.getApnType());
            //清除DataConnection
            apnContext.setDataConnectionAc(null);
            //如果所有APN都发生Permanent fail,则不做重试
            if (apnContext.getWaitingApnsPermFailCount() == 0) {
   
                if (DBG) {
   
                    log("onDataSetupCompleteError: All APN's had permanent failures, stop retrying");
                }
            } else {
   //执行重试
                int delay = getApnDelay(Phone.REASON_APN_FAILED);
                if (DBG) {
   
                    log("onDataSetupCompleteError: Not all APN's had permanent failures delay="+ delay);
                }
                startAlarmForRestartTrySetup(del

你可能感兴趣的:(android)