Android URC 介绍及源码案例参考

1. URC 含义

URC 是 Unsolicited Result Code非请求结果码)的缩写。

  • 它是 modem(基带)在不需要 AP 主动请求的情况下向上层主动上报的消息
  • 典型例子:短信到达提示、网络状态变更、来电通知、信号质量变化等。
  • URC 一般以 AT 命令扩展的形式从 modem 发到 AP,例如串口、QMI、RIL 通道。
  • URC 通常以字符串或特定消息 ID 的形式携带信息,比如:
    +CMTI: "SM",3
    RING
    +CREG: 1,"1234","5678"
    
    这些信息不是某个 AT command 的直接响应,而是 modem 主动推送的。

2. 在 Android 中 modem URC 的处理流程

在 Android 平台,modem 与 Android Telephony Framework 通信主要通过 RIL(Radio Interface Layer)
URC 在 Android 中通常叫 Unsolicited Response(非请求消息),它的流程大致如下:

典型处理链路

Modem(基带模块)
    ↓  (AT字符串, QMI, 或其它协议)
RIL Daemon (rild)     -->  Vendor RIL 实现
    ↓
RILJ (Java层 Radio Interface Layer)
    ↓
PhoneBase / GsmCdmaPhone / ServiceStateTracker 等
    ↓
TelephonyManager / Broadcast / App
  1. modem --> Vendor RIL
    Modem 通过串口 / QMI / IPC 接口向 vendor RIL driver 上报 URC,vendor RIL driver 收到数据后,调用 RIL_onUnsolicitedResponse() 通知上层。
    mtk ril

  2. Vendor RIL --> rild (RIL Daemon)
    rild 进程读取并解析这些非请求 URC,然后通过 libril.so 提供的回调封装成 RadioIndication 发送给 Java 层。

  3. RILJ(Java层)
    在 frameworks/opt/telephony/RIL.java 中有很多处理 unsolicited 事件的 case,例如:

    case RIL_UNSOL_RESPONSE_NEW_SMS:
        if (RILJ_LOGD) unsljLogRet(response, ret);
        if (mSmsRegistrant != null) {
         
         
            mSmsRegistrant.notifyRegistrant(
                new AsyncResult(null, ret, null));
        }
        break;
    case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED:
        pollCallsWhenSafe();
        break;
    

    这些就是 modem 上报 URC(短信、新呼叫、网络状态变更等)的处理入口。

  4. Telephony Framework --> Apps
    上层组件(ServiceStateTrackerGsmCdmaCallTrackerInboundSmsHandler 等)根据收到的 URC 更新状态并向应用广播,例如:

    • 短信到达:会发出 SMS_RECEIVED 广播。
    • 来电:触发 Telephony UI 更新,启动拨号界面。
    • 网络状态变更:通过 ServiceState 回调给 TelephonyManager

3. Android 上可以参考的功能代码

URC 在 Android 中处理方案可以参考 AOSP 源码,位置大概如下:

C/C++ 层(RIL Daemon 与 Vendor RIL 接口)

  • hardware/ril/libril/ril.cpp
    • 函数:RIL_onUnsolicitedResponse()
      用来把 modem 上报的 URC 往 Java 层送。
  • hardware/ril/libril/ 中的核心处理

Java 层(RILJ)

  • frameworks/opt/telephony/src/java/com/android/internal/telephony/RIL.java
    • processUnsolicited() 方法:集中处理底层来的 URC
    • 不同的 case 对应不同的 RIL_UNSOL_* 常量。
  • frameworks/opt/telephony/src/java/com/android/internal/telephony/gsm/GsmServiceStateTracker.java
    • 处理网络注册相关的 URC
  • frameworks/opt/telephony/src/java/com/android/internal/telephony/InboundSmsHandler.java
    • 处理短信的 URC(RIL_UNSOL_RESPONSE_NEW_SMS
  • frameworks/opt/telephony/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java
    • 处理来电(RIL_UNSOL_CALL_STATE_CHANGED

4. 一个简单的 URC 上报示例

假设 modem 收到一条新的短信,会发出 URC:

+CMTI: "SM",3

处理流程:

  1. modem 主动通过 AT 接口发送 +CMTI URC 给 RIL。
  2. Vendor RIL 在解析到 +CMTI 后调用:
    RIL_onUnsolicitedResponse(RIL_UNSOL_RESPONSE_NEW_SMS, pduData, pduLen);
    
  3. libril 通知 RILJ(Java 层):
    case RIL_UNSOL_RESPONSE_NEW_SMS:
        mSmsRegistrant.notifyRegistrant(
            new AsyncResult(null, ret, null));
    
  4. InboundSmsHandler 收到通知,存储短信并发 SMS_RECEIVED 广播给上层应用。

总结

  • URC:modem 主动通知上层的异步消息,RIL 叫 unsolicited response。
  • Android 中可参考:
    • C/C++:hardware/ril/libril/ril.cpp(RIL_onUnsolicitedResponse)
    • Java:RIL.javaprocessUnsolicited 逻辑
    • 各 tracker(ServiceStateTracker、CallTracker、InboundSmsHandler)的注册与处理。
  • 为了调试,可以开 modem log(AT 口)结合 adb logcat -b radio 看 u-r-c 相关日志。

URC 在 Android 处理的时序图
URC(Unsolicited Result Code)Android 处理流程时序图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值