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 扩展框架!关键是保持 分层调用链 的一致性。