1. 什么是 QCRIL?
QCRIL = Qualcomm C RIL (高通 C 语言 RIL)
- QCRIL 是高通为其 Snapdragon 处理器开发的 RIL 实现
- 是一个原始厂商提供的电话接口库,实现了 Android 的 RIL 接口
- 负责与高通调制解调器通信,处理电话功能
2. 什么是 QMI?
QMI = Qualcomm Message Interface (高通消息接口)
- QMI 是高通定义的通信协议,用于与调制解调器(Modem)通信
- 是 QCRIL 的底层通信协议
- 运行在内核中,通过
/dev/qmi设备进行通信
关键特点:
- 基于消息的通信协议
- 使用 TLV (Tag-Length-Value) 编码格式
- 支持多个服务(Service),每个服务负责不同的功能
3. QCRIL 和 QMI 的关系
Android Framework (Phone App)
↓
RIL Daemon (rild)
↓
QCRIL Library (vendor-specific RIL implementation)
↓
QMI Protocol (/dev/qmi device)
↓
Modem (高通调制解调器)
4. 代码示例:QMI 数据连接建立
从 reference-ril.c 可以看到 QMI 的实际使用:
1916| fd = open ("/dev/qmi", O_RDWR); // 打开QMI设备
1917| if (fd >= 0) { /* the device doesn't exist on the emulator */
1918|
1919| RLOGD("opened the qmi device\n");
1920| asprintf(&cmd, "up:%s", apn); // 构造命令:up:APN名称
1921| len = strlen(cmd);
1922|
1923| while (cur < len) {
1924| do {
1925| written = write (fd, cmd + cur, len - cur); // 发送QMI命令给modem
1926| } while (written < 0 && errno == EINTR);
1927| }
1928|
1929| // 等待接口上线
1930| do {
1931| sleep(1);
1932| do {
1933| rlen = read(fd, status, 31); // 读取modem响应
1934| } while (rlen < 0 && errno == EINTR);
1935| } while (strncmp(status, "STATE=up", 8) && strcmp(status, "online") && --retry);
数据连接流程:
| 步骤 | 操作 |
|---|---|
| 1 | RIL 接收 RIL_REQUEST_SETUP_DATA_CALL 请求 |
| 2 | QCRIL 打开 /dev/qmi 设备 |
| 3 | 发送 QMI 命令:up:apn_name |
| 4 | Modem 处理 QMI 消息,建立数据连接 |
| 5 | 读取 Modem 响应状态 (STATE=up 或 online) |
| 6 | 配置网络接口 (netcfg rmnet0 dhcp) |
| 7 | 返回数据连接结果给 Android Framework |
5. QMI 服务类型
QMI 定义了多个服务,用于处理不同类型的请求:
| QMI 服务 | 功能 | 关联的 RIL 请求 |
|---|---|---|
| WDS (Wireless Data Service) | 数据连接、分组数据 | SETUP_DATA_CALL, DEACTIVATE_DATA_CALL |
| NAS (Network Access Service) | 网络注册、信号强度、服务状态 | VOICE_REGISTRATION_STATE, DATA_REGISTRATION_STATE |
| QMI_CTL | QMI 控制和初始化 | 基础初始化 |
| SMS | 短信服务 | SEND_SMS, RECEIVE_SMS |
| DMS (Device Management Service) | 设备管理 | 获取 IMEI、IMSI 等 |
| UIM (USIM Interface) | SIM 卡管理 | SIM_IO, GET_SIM_STATUS |
6. RIL 请求处理流程
以 RIL_REQUEST_SETUP_DATA_CALL 为例:
Java 层 (ConnectivityManager)
↓
RIL.java (java/com/android/internal/telephony/)
↓
radio::setupDataCallResponse (ril_service.cpp)
↓
QCRIL (vendor library)
↓
QMI WDS Service (Write to /dev/qmi)
↓
Modem (执行数据连接)
↓
QMI WDS Response (Read from /dev/qmi)
↓
RIL_onRequestComplete() 回调
↓
Java 层获得结果,更新网络状态
7. 实际的 RIL 请求处理
从 ril_service.cpp 看数据调用请求:
Return<void> RadioImpl::setupDataCall(
int32_t serial,
RadioTechnology radioTechnology,
const DataProfileInfo& dataProfileInfo,
bool modemCognitive,
bool roamingAllowed,
bool isRoaming) {
// 构造 RIL_REQUEST_SETUP_DATA_CALL 请求参数
dispatchStrings(serial, mSlotId, RIL_REQUEST_SETUP_DATA_CALL, true, 15,
std::to_string((int) radioTechnology + 2).c_str(),
std::to_string((int) dataProfileInfo.profileId).c_str(),
dataProfileInfo.apn.c_str(), // APN 名称
dataProfileInfo.user.c_str(), // 用户名
dataProfileInfo.password.c_str(), // 密码
std::to_string((int) dataProfileInfo.authType).c_str(),
dataProfileInfo.protocol.c_str(), // IP/IPv6/IPV4V6
// ... 更多参数
);
}
8. QCRIL 的优势
| 优势 | 说明 |
|---|---|
| 高性能 | 针对高通 Modem 优化 |
| 功能完整 | 支持所有高通 Modem 特性 |
| 稳定性 | 经过严格测试 |
| 低延迟 | 直接通过 QMI 协议与 Modem 通信 |
9. 关键文件位置
| 文件 | 功能 |
|---|---|
hardware_ril/reference-ril/reference-ril.c | 参考 RIL 实现 |
hardware_ril/libril/ril.cpp | RIL 核心库 |
hardware_ril/libril/ril_service.cpp | RIL HAL 服务适配 |
hardware_ril/include/telephony/ril.h | RIL 接口定义 |
10. 总结
- QCRIL 是高通实现的 RIL,遵循 Android 的 RIL 接口规范
- QMI 是 QCRIL 与 Modem 通信的底层协议
- QMI 通过
/dev/qmi设备驱动与内核交互 - 所有电话功能(通话、短信、数据等)都通过 QMI 消息在 QCRIL 和 Modem 之间传输
- QCRIL + QMI 构成了 Android 系统与高通 Modem 通信的桥梁
这个架构确保了 Android 系统与不同厂商 Modem 的兼容性,同时为厂商提供了优化其硬件的机会。