RIL命令集扩展完整指南

7 阅读5分钟

RIL命令集扩展完整指南

第1层:框架架构理解

RIL命令的传递链路:

Framework(Java) → CommandsInterface → RIL(Java)
                                        ↓
                    RadioServiceProxy(HAL代理) → HIDL/AIDL服务
                                        ↓
                    Vendor HAL实现(C++)  → Modem固件
                                        ↓
                    响应流程逆向

第2层:核心组件分解

A. 常量定义 - RILConstants.java

// 1. 定义新的RIL请求常量
public class RILConstants {
    // 从 RIL_REQUEST_HAL_NON_RIL_BASE 开始
    int RIL_REQUEST_MY_CUSTOM_CMD_1 = 200;      // 自定义命令ID
    int RIL_REQUEST_MY_CUSTOM_CMD_2 = 201;
    
    // 对应的unsol消息
    int RIL_UNSOL_MY_CUSTOM_INDICATION_1 = 3000;
    int RIL_UNSOL_MY_CUSTOM_INDICATION_2 = 3001;
}

B. 接口定义 - CommandsInterface.java

// 2. 在CommandsInterface中声明新的方法
public interface CommandsInterface {
    /**
     * 发送自定义命令到Modem
     * @param params 命令参数
     * @param result 响应回调Message
     */
    void sendCustomCommand(String params, Message result);
    
    /**
     * 查询自定义状态
     * @param queryId 查询ID
     * @param result 响应回调Message
     */
    void queryCustomStatus(int queryId, Message result);
    
    // 注册监听器
    void registerForCustomIndication(Handler h, int what, Object obj);
    void unregisterForCustomIndication(Handler h);
}

C. 声明监听器接口

// CommandsInterface.java 中
void setOnCustomEvent(Handler h, int what, Object obj);
void unsetOnCustomEvent(Handler h);

第3层:Java层实现 - RIL.java

public class RIL extends BaseCommands implements CommandsInterface {
    // ===== 第1步:添加事件处理器 =====
    private RegistrantList mCustomEventRegistrants = new RegistrantList();
    
    // ===== 第2步:实现接口方法 =====
    @Override
    public void sendCustomCommand(String params, Message result) {
        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class);
        
        // 版本检查
        if (!canMakeRequest("sendCustomCommand", networkProxy, result, 
                new HalVersion(2, 1))) {
            return;
        }
        
        // 创建RIL请求
        RILRequest rr = obtainRequest(RIL_REQUEST_MY_CUSTOM_CMD_1, result, 
                mRILDefaultWorkSource);
        
        if (RILJ_LOGD) {
            riljLog(rr.serialString() + "> sendCustomCommand: " + params);
        }
        
        // 调用代理方法
        radioServiceInvokeHelper(HAL_SERVICE_NETWORK, rr, "sendCustomCommand", () -> {
            networkProxy.sendCustomCommand(rr.mSerial, params);
        });
    }
    
    @Override
    public void queryCustomStatus(int queryId, Message result) {
        RadioNetworkProxy networkProxy = getRadioServiceProxy(RadioNetworkProxy.class);
        
        if (!canMakeRequest("queryCustomStatus", networkProxy, result, 
                new HalVersion(2, 1))) {
            return;
        }
        
        RILRequest rr = obtainRequest(RIL_REQUEST_MY_CUSTOM_CMD_2, result,
                mRILDefaultWorkSource);
        
        if (RILJ_LOGD) {
            riljLog(rr.serialString() + "> queryCustomStatus: queryId=" + queryId);
        }
        
        radioServiceInvokeHelper(HAL_SERVICE_NETWORK, rr, "queryCustomStatus", () -> {
            networkProxy.queryCustomStatus(rr.mSerial, queryId);
        });
    }
    
    // ===== 第3步:实现监听器注册 =====
    @Override
    public void setOnCustomEvent(Handler h, int what, Object obj) {
        mCustomEventRegistrants.add(new Registrant(h, what, obj));
    }
    
    @Override
    public void unsetOnCustomEvent(Handler h) {
        mCustomEventRegistrants.remove(h);
    }
    
    // ===== 第4步:处理响应 =====
    // 响应由 RadioNetworkResponse 类处理(见下文)
    
    // ===== 第5步:处理主动上报(Unsolicited Indication) =====
    public void onCustomIndication(String data) {
        if (RILJ_LOGD) {
            riljLog("onCustomIndication: " + data);
        }
        
        mCustomEventRegistrants.notifyRegistrants(
                new AsyncResult(null, data, null));
    }
}

第4层:Response类实现 - NetworkResponse.java

public class NetworkResponse extends IRadioNetworkResponse.Stub {
    private final RIL mRil;
    
    public NetworkResponse(RIL ril) {
        mRil = ril;
    }
    
    /**
     * 处理sendCustomCommand的响应
     */
    public void sendCustomCommandResponse(RadioResponseInfo responseInfo, String result) {
        RILRequest rr = mRil.processResponse(HAL_SERVICE_NETWORK, responseInfo);
        
        if (rr != null) {
            if (responseInfo.error == RadioError.NONE) {
                // 成功:将结果通过Message传回
                RadioResponse.sendMessageResponse(rr.mResult, result);
            }
            mRil.processResponseDone(rr, responseInfo, result);
        }
    }
    
    /**
     * 处理queryCustomStatus的响应
     */
    public void queryCustomStatusResponse(RadioResponseInfo responseInfo, 
            CustomStatusInfo statusInfo) {
        RadioResponse.responseParcelable(HAL_SERVICE_NETWORK, mRil, responseInfo, 
                statusInfo);
    }
}

第5层:Indication处理 - Unsolicited Indication

// 在 NetworkIndication.java 中
public class NetworkIndication extends IRadioNetworkIndication.Stub {
    private final RIL mRil;
    
    /**
     * 处理主动上报的Custom事件
     */
    public void onCustomEvent(int indicationType, String eventData) {
        if (RIL.RILJ_LOGD) {
            RIL.unsljLog("onCustomEvent: " + eventData);
        }
        
        mRil.onCustomIndication(eventData);
    }
}

第6层:HIDL/AIDL服务层

AIDL接口定义 - IRadioNetwork.aidl

// hardware_interfaces/radio/aidl/android/hardware/radio/network/IRadioNetwork.aidl

package android.hardware.radio.network;

oneway interface IRadioNetwork {
    /**
     * 发送自定义命令
     * @param serial 唯一的请求序列号
     * @param commandData 命令数据
     */
    void sendCustomCommand(in int serial, in String commandData);
    
    /**
     * 查询自定义状态
     * @param serial 唯一的请求序列号  
     * @param queryId 查询类型ID
     */
    void queryCustomStatus(in int serial, in int queryId);
}

oneway interface IRadioNetworkResponse {
    /**
     * 响应sendCustomCommand请求
     */
    void sendCustomCommandResponse(in android.hardware.radio.RadioResponseInfo info, 
            in String result);
    
    /**
     * 响应queryCustomStatus请求
     */
    void queryCustomStatusResponse(in android.hardware.radio.RadioResponseInfo info,
            in CustomStatusInfo status);
}

oneway interface IRadioNetworkIndication {
    /**
     * 主动上报自定义事件
     */
    void onCustomEvent(in int indicationType, in String eventData);
}

数据类型定义 - CustomStatusInfo.aidl

package android.hardware.radio.network;

parcelable CustomStatusInfo {
    int statusCode;
    String statusDescription;
    int[] additionalData;
}

第7层:HAL实现(C++)- RadioNetwork.cpp

// hardware_interfaces/radio/aidl/impl/RadioNetwork.cpp

#include <android/hardware/radio/network/IRadioNetwork.h>
#include "RadioNetwork.h"
#include "radio.h"

namespace android::hardware::radio::network {

Return<void> RadioNetwork::sendCustomCommand(int32_t serial, const std::string& commandData) {
    RLOGD("sendCustomCommand: serial=%d, command=%s", serial, commandData.c_str());
    
    // 转发到RIL
    std::string cmd = "AT+CUSTOMCMD=" + commandData;
    
    // 调用modem驱动或socket接口
    sendAtCommand(serial, cmd, RIL_REQUEST_MY_CUSTOM_CMD_1);
    
    return Void();
}

Return<void> RadioNetwork::queryCustomStatus(int32_t serial, int32_t queryId) {
    RLOGD("queryCustomStatus: serial=%d, queryId=%d", serial, queryId);
    
    // 构造AT命令
    std::string cmd = "AT+CUSTOMSTAT=" + std::to_string(queryId);
    
    sendAtCommand(serial, cmd, RIL_REQUEST_MY_CUSTOM_CMD_2);
    
    return Void();
}

// 处理AT命令响应
void handleCustomCmdResponse(int request, const char* s, RIL_Token t) {
    switch (request) {
        case RIL_REQUEST_MY_CUSTOM_CMD_1: {
            // 解析响应
            CustomStatusInfo info;
            info.statusCode = 0;
            info.statusDescription = s;
            
            radioNetwork->sendCustomCommandResponse(
                RadioResponseInfo{
                    .type = RadioResponseType::SOLICITED,
                    .serial = serial,
                    .error = RadioError::NONE
                },
                info
            );
            break;
        }
        case RIL_REQUEST_MY_CUSTOM_CMD_2: {
            // 解析状态信息
            CustomStatusInfo status;
            parseStatus(s, &status);
            
            radioNetwork->queryCustomStatusResponse(
                RadioResponseInfo{...},
                status
            );
            break;
        }
    }
}

// 处理Unsolicited Indication
void onCustomEventNotification(const std::string& eventData) {
    RLOGD("onCustomEventNotification: %s", eventData.c_str());
    
    radioIndication->onCustomEvent(
        RadioIndicationType::UNSOLICITED,
        eventData
    );
}

} // namespace

第8层:集成层 - BaseCommands.java

// frameworks_opt_telephony/src/java/com/android/internal/telephony/BaseCommands.java

public abstract class BaseCommands implements CommandsInterface {
    // 已有的代码...
    
    // 添加新方法的默认实现或声明
    protected RegistrantList mCustomEventRegistrants;
    
    @Override
    public void sendCustomCommand(String params, Message result) {
        // 默认实现:返回错误
        AsyncResult.forMessage(result, null, 
                CommandException.fromRilErrno(CommandException.GENERIC_FAILURE));
        result.sendToTarget();
    }
    
    @Override
    public void setOnCustomEvent(Handler h, int what, Object obj) {
        mCustomEventRegistrants.add(new Registrant(h, what, obj));
    }
}

第9层:逐步扩展清单

步骤1:定义常量(涉及文件:3个)

✅ RILConstants.java          - 添加 RIL_REQUEST_MY_CUSTOM_*
✅ RILUtils.java             - 添加 requestToString() case
✅ RILUtils.java             - 添加 unsolicited requestToString() case

步骤2:定义接口(涉及文件:1个)

✅ CommandsInterface.java     - 添加新方法签名

步骤3:Java实现(涉及文件:4个)

✅ RIL.java                   - 实现方法 + 响应处理
✅ BaseCommands.java          - 默认实现
✅ NetworkResponse.java       - 处理响应回调
✅ NetworkIndication.java     - 处理Unsolicited指示

步骤4:AIDL/数据类型(涉及文件:3个)

✅ IRadioNetwork.aidl
✅ IRadioNetworkResponse.aidl
✅ CustomStatusInfo.aidl

步骤5:HAL实现(涉及文件:2个)

✅ RadioNetwork.cpp           - 实现AIDL方法
✅ RadioNetwork.h             - 声明处理函数

第10层:调用示例

// 使用者代码(SystemService或Phone)
public class MyTelephonyService {
    private RIL mRil;
    
    // 1. 发送自定义命令
    public void executeCustomCommand(String param) {
        Handler handler = new Handler(msg -> {
            if (msg.what == MY_CUSTOM_CMD_DONE) {
                AsyncResult ar = (AsyncResult) msg.obj;
                if (ar.exception != null) {
                    Log.e(TAG, "Command failed: " + ar.exception);
                } else {
                    String result = (String) ar.result;
                    Log.d(TAG, "Result: " + result);
                }
            }
        });
        
        Message msg = handler.obtainMessage(MY_CUSTOM_CMD_DONE);
        mRil.sendCustomCommand(param, msg);
    }
    
    // 2. 监听主动上报
    public void registerCustomEvents() {
        Handler handler = new Handler(msg -> {
            if (msg.what == CUSTOM_EVENT_NOTIFICATION) {
                AsyncResult ar = (AsyncResult) msg.obj;
                String eventData = (String) ar.result;
                Log.d(TAG, "Event: " + eventData);
            }
        });
        
        mRil.setOnCustomEvent(handler, CUSTOM_EVENT_NOTIFICATION, null);
    }
}

第11层:测试验证

// 单元测试框架
public class RILCustomCommandTest {
    @Test
    public void testSendCustomCommand() {
        // 模拟Modem响应
        String mockResponse = "OK";
        
        // 调用方法
        Message result = handler.obtainMessage();
        ril.sendCustomCommand("TEST_PARAM", result);
        
        // 验证Message是否被发送
        assertTrue(mMessageCaptor.getValue() != null);
    }
}

快速参考表

步骤文件改动关键代码
1️⃣RILConstants.java+2行int RIL_REQUEST_MY_CUSTOM = 200;
2️⃣CommandsInterface.java+3行void sendCustomCommand(...)
3️⃣RIL.java+40行实现方法 + 响应处理
4️⃣NetworkResponse.java+15行响应回调
5️⃣NetworkIndication.java+10行Indication处理
6️⃣IRadioNetwork.aidl+10行AIDL方法
7️⃣RadioNetwork.cpp+50行HAL实现

这就是完整的 RIL 扩展框架!关键是保持 分层调用链 的一致性。