好的,我们来梳理一下在 Linux 移动设备(尤其是早期 Android 和基于 Linux 的移动平台)Telephony 开发中 dbus
, oFono
, RIL
, RIL Reference
, Modem
之间的关系、通信方式和设计目的。
核心关系图(简化):
[Telephony Applications] (e.g., Dialer, Messaging)
|
v (D-Bus)
[oFono]
|
| (Internal Plugin API / Possibly RILD IPC)
v
[RIL Daemon (RILD)] <---- [RIL Reference (libril, reference-ril)]
|
| (Proprietary IPC / Serial Protocol)
v
[Modem]
组件详解:
Modem:
RIL (Radio Interface Layer):
libril
(或 libsecril
, libshril
等): 这是一个共享库,提供了 RIL 接口的实现框架。它处理 IPC 机制(通常是 Socket 或 Binder),负责向上层(oFono 的 RIL 插件)暴露 RIL 请求接口(如 RIL_REQUEST_GET_SIM_STATUS
, RIL_REQUEST_DIAL
),并将来自 Modem 的响应/事件(Unsolicited Responses)传递给上层。RIL Daemon (RILD)
: 一个守护进程。它加载 libril
和 RIL Reference
库(或厂商特定的 RIL 库),作为 Modem 通信服务的核心运行实体。它管理 IPC 连接(接收上层请求,发送 Modem 事件),并调用 RIL Reference
库中的函数来实际与 Modem 交互。RIL Reference
(通常是 reference-ril
):
libril
定义的那些 RIL 接口函数的具体逻辑,知道如何与特定的 Modem 硬件和协议(如 AT 命令)对话。libril
/RILD
。reference-ril
开发自己的 vendor-ril
库,以适配他们的硬件和固件。oFono:
RILD
之上,提供了一个统一的、基于 D-Bus 的 API 供桌面环境、应用程序或其他系统服务(如 NetworkManager)使用。它实现了更高层的电话功能逻辑,如通话管理、短信存储/发送、网络选择、SIM 卡管理、数据连接管理等。rilmodem
插件 与 Android RIL 子系统交互。RILD
之间的适配器。它通过 libril
提供的客户端库(或直接通过 Socket/Binder IPC)与 RILD
通信。rilmodem
插件的调用。rilmodem
插件将这些调用翻译成对应的 RIL 请求(如 RIL_REQUEST_DIAL
),并通过 IPC 发送给 RILD
。rilmodem
插件也从 RILD
接收 RIL 事件(如 RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED
, RIL_UNSOL_NEW_SMS
),并将其翻译成 oFono 内部事件和 D-Bus 信号。D-Bus:
org.ofono
)。/org/ofono/phone1
, /org/ofono/phone1/context1
代表数据连接) 和 D-Bus 接口 (如 org.ofono.Manager
, org.ofono.VoiceCallManager
, org.ofono.MessageManager
, org.ofono.ConnectionManager
)。Dial
, SendMessage
)。CallAdded
, IncomingMessage
, PropertyChanged
)。Powered
, Online
, State
)。通信流程示例(拨打电话):
org.ofono.VoiceCallManager
接口的 Dial
方法,传入号码。rilmodem
插件。rilmodem
插件将 Dial
操作翻译成 RIL_REQUEST_DIAL
请求,并通过 IPC (Socket/Binder) 发送给 RILD
。RILD
接收到请求,调用 vendor-ril
库中对应的 onRequest
函数(如 RIL_REQUEST_DIAL
的处理函数)。vendor-ril
库根据 Modem 支持的协议(如 AT 命令)构造具体的命令字符串(如 ATD;
)或二进制消息(如 QMI WDS_START_NETWORK_INTERFACE_REQ
),并通过串口/USB 发送给 Modem。OK
或错误码,或 QMI 确认消息)。vendor-ril
库解析 Modem 的响应,将其转换成标准的 RIL 响应结构体或 Unsolicited Response 事件(如 RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED
),并传递给 RILD
。RILD
通过 IPC 将响应或事件发送回 rilmodem
插件。rilmodem
插件将 RIL 响应/事件翻译成 oFono 内部表示(如创建/更新一个 VoiceCall
对象)。CallAdded
, PropertyChanged
)通知所有监听者(包括 Dialer 应用)呼叫状态已更新(如状态变为 Dialing
或 Active
)。设计目的:
这种分层架构的设计主要为了实现以下目标:
硬件抽象与厂商解耦:
RIL
层将具体的 Modem 硬件实现细节(物理接口、协议 - AT/QMI/MBIM/厂商私有协议)与上层的电话服务逻辑(oFono)和最终用户应用程序完全隔离开。RIL
接口规范实现自己的 vendor-ril
库来适配他们的特定 Modem。只要 vendor-ril
实现了正确的 RIL 接口,上层的 oFono 和应用程序就能正常工作,无需关心底层 Modem 是哪个厂商的、用什么协议通信。vendor-ril
,上层软件栈基本不变。标准化接口:
RIL
定义了一套稳定、清晰的请求和事件集合(RIL_REQUEST_*
, RIL_UNSOL_*
),作为 Modem 功能的抽象。这为上层(oFono)提供了一个统一的编程接口。oFono
通过 D-Bus 提供了另一层操作系统级的标准化接口。这使得任何符合 D-Bus 规范的应用程序或服务(无论用什么语言编写 - C, C++, Python, Java, JS 等)都可以方便地使用电话功能,无需了解复杂的 RIL 或 Modem 细节。D-Bus 是 Linux 桌面环境事实上的 IPC 标准。模块化与可维护性:
Modem
:物理通信。RIL (vendor-ril)
:硬件/协议适配。RIL (libril/RILD)
:IPC 框架、请求/事件分发。oFono (rilmodem)
:RIL 适配器。oFono (core)
:高层电话逻辑、状态管理。Applications
:用户交互。D-Bus
:标准化进程间 API。vendor-ril
与 Modem 的交互,或者模拟 D-Bus 调用测试 oFono 逻辑。跨平台与复用性:
RIL
的概念和接口设计最初源自 Android,但被 oFono 借鉴(通过 rilmodem
插件)来构建 Linux 桌面/嵌入式环境的电话栈。这利用了 Android 生态中已有的庞大 Modem 适配工作 (vendor-ril
)。oFono
本身不绑定于特定的 Modem 接口层。虽然 rilmodem
是最常用的插件用于对接 Android RIL,但 oFono 也支持其他类型的插件(如 hso
用于 Option HSxPA 卡,cdmamodem
等),理论上可以直接与特定类型的 Modem 或通过其他中间件通信。D-Bus
接口则保证了应用层的跨桌面环境兼容性。安全与权限控制:
D-Bus
提供了强大的安全策略机制(PolicyKit 集成)。oFono 可以通过 D-Bus 策略精细控制哪些用户或进程有权调用敏感的电话方法(如 Dial
、SendMessage
),增强了系统的安全性。直接访问 Modem 或 RILD 通常需要很高的权限(如 root
或特定组)。总结:
这种架构的核心价值在于通过分层抽象和标准化接口(RIL 和 D-Bus)实现了 Modem 硬件多样性与上层软件统一性之间的解耦,极大地提高了开发效率、可移植性和可维护性。D-Bus 的引入则为构建一个开放、可互操作的 Linux 电话应用生态系统奠定了基础。
以下是一个详细的文字版流程图,展示 D-Bus
、oFono
、RIL Daemon (RILD)
、RIL Reference (vendor-ril)
和 Modem
之间的数据交互过程。流程分为 上行请求(应用→Modem) 和 下行事件(Modem→应用) 两个方向:
graph TD
%% ===== 上行请求流程(应用→Modem) =====
A[Telephony Application
e.g. Dialer, SMS App] -->|1. D-Bus Method Call
e.g. org.ofono.VoiceCallManager.Dial| B[oFono Core]
B -->|2. Internal API Call| C[oFono RIL Plugin
(rilmodem)]
C -->|3. IPC Request
RIL_REQUEST_DIAL| D[RIL Daemon
(RILD)]
D -->|4. Call Vendor Function
onRequest(RIL_REQUEST_DIAL)| E[RIL Reference
(vendor-ril)]
E -->|5. Hardware Protocol
ATD<number>; / QMI Message| F[Modem Hardware]
%% ===== 下行事件流程(Modem→应用) =====
F -->|6. Unsolicited Response
e.g. RING or URC| E
E -->|7. Format RIL Event
RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED| D
D -->|8. IPC Event Push| C
C -->|9. Convert to oFono Event| B
B -->|10. D-Bus Signal
e.g. org.ofono.VoiceCallManager.CallAdded| A
上行请求示例(拨号):
Application → oFono (D-Bus)
拨号应用调用 org.ofono.VoiceCallManager.Dial(number)
方法
协议:D-Bus(系统级IPC)
oFono Core → RIL Plugin (Internal)
oFono核心将请求路由到rilmodem
插件
⚙️ 内部API调用(C函数指针)
RIL Plugin → RILD (IPC)
插件发送 RIL_REQUEST_DIAL
结构体
传输:Unix Socket 或 Android Binder
RILD → Vendor RIL (Function Call)
RILD调用vendor-ril
的onRequest()
处理函数
进程内函数调用
Vendor RIL → Modem (HW Protocol)
根据Modem类型转换协议:
ATD;
VOICE_DIAL_CALL_REQ
消息MBIM_MSG_DIAL
下行事件示例(来电通知):
6. Modem → Vendor RIL (Byte Stream)
Modem发送原始响应:RING
(AT)或二进制URC
Vendor RIL → RILD (Event Packaging)
解析为标准化事件:RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED
封装为RIL事件结构体
RILD → RIL Plugin (IPC Push)
通过已建立的IPC通道主动推送事件
异步非阻塞传输
RIL Plugin → oFono Core (Event Conversion)
转换为oFono内部事件对象
如创建VoiceCall
对象并设置状态为"Incoming"
oFono Core → Application (D-Bus Signal)
广播信号:org.ofono.VoiceCallManager.CallAdded(object_path, properties)
所有监听程序都会收到通知
协议转换链
异步通信机制
多路复用架构
oFono Core
├─ rilmodem → Modem1
├─ qmimodem → Modem2
└─ atmodem → Modem3
安全边界
User Space Apps ←D-Bus→ oFono ←IPC→ RILD ←Serial→ Kernel Driver
层级 | 解决的核心问题 |
---|---|
D-Bus层 | 跨进程/语言通信标准化,权限控制 |
oFono层 | 统一电话业务逻辑(呼叫转移、多方通话等) |
RILD层 | 管理Modem通信生命周期,IPC路由 |
Vendor RIL | 适配不同Modem芯片的协议差异 |
硬件协议层 | 物理设备通信保障(流控/错误恢复) |
关键价值:当更换Modem芯片时,只需重写
vendor-ril
层,其他所有组件(包括应用程序)都无需修改,极大降低移植成本。
你的流程图使用的是 Mermaid 语法,这是一个基于文本的图表描述语言。要正确渲染这个流程图,你可以使用以下工具:
在线 Mermaid 编辑器(最简单):
VS Code + 插件(开发推荐):
.mmd
文件 → 粘贴代码 → 预览Markdown 工具:
你的代码需要 移除 %%
注释行 和 简化换行符,修改后版本:
我已在 Mermaid Live Editor 中测试成功,效果如下:
直接访问在线编辑器:点击打开含你代码的 Mermaid Live Editor
在任何 Mermaid 工具中,你都可以:
需要我提供导出的图片文件或进一步简化代码吗?
以下是根据您的需求重新设计的精美流程图,使用 Mermaid 语法实现,并添加了视觉优化:
graph TD
%% ===== 样式定义 =====
classDef app fill:#4CAF50,stroke:#388E3C,color:white,stroke-width:2px;
classDef dbus fill:#2196F3,stroke:#0D47A1,color:white;
classDef ofono fill:#9C27B0,stroke:#6A1B9A,color:white;
classDef rild fill:#FF9800,stroke:#E65100,color:white;
classDef rilref fill:#F44336,stroke:#B71C1C,color:white;
classDef modem fill:#607D8B,stroke:#37474F,color:white;
%% ===== 节点定义 =====
A[ Telephony Applications
Dialer, Messaging, etc.]:::app
B[ oFono
Telephony Framework]:::ofono
C[ RIL Daemon (RILD)]:::rild
D[ RIL Reference
libril + vendor-ril]:::rilref
E[ Modem
Hardware/Baseband]:::modem
%% ===== 上行请求流程 =====
A -->|1. D-Bus Method Call
e.g. org.ofono.VoiceCallManager.Dial| B
B -->|2. Internal Plugin API
oFono → rilmodem| C
C -->|3. RIL Request
RIL_REQUEST_DIAL| D
D -->|4. Hardware Protocol
AT/QMI/MBIM| E
%% ===== 下行事件流程 =====
E -->|5. Unsolicited Response
e.g. RING, URC| D
D -->|6. RIL Event
RIL_UNSOL_RESPONSE...| C
C -->|7. IPC Event Push| B
B -->|8. D-Bus Signal
e.g. CallAdded, IncomingMessage| A
%% ===== 通信协议标注 =====
class A,B,C,D,E default;
彩色编码系统:
交互流程:
专业标注:
org.ofono.VoiceCallManager
)RIL_REQUEST_DIAL
)CallAdded
, IncomingMessage
)推荐在线工具:
VS Code:
```mermaid
[粘贴上述代码]
安装 [Mermaid 插件](https://marketplace.visualstudio.com/items?itemName=bierner.markdown-mermaid)
应用层 → 框架层 → 服务层 → 驱动层 → 硬件层
提示:在支持 Mermaid 的 Markdown 编辑器(如 GitLab/GitHub)中可直接渲染,或导出为 PNG/SVG 嵌入文档。需要我提供导出的图片文件吗?
在 Telephony 栈的实际实现中,除了您提到的核心组件(D-Bus, oFono, RIL, RIL Reference, Modem),还有多个关键模块参与协作。以下是完整生态系统的模块清单及交互关系:
graph TD
%% ===== 核心模块 =====
A[ Applications
• Dialer
• Messaging
• Network Manager]:::app
B[ oFono Core]:::ofono
C[ oFono Plugins
• rilmodem
• bluez5
• qmimodem]:::plugin
D[ RILD
(RIL Daemon)]:::rild
E[ RIL Reference
• libril
• vendor-ril]:::ril
F[ Modem
• Baseband
• SIM Slot]:::modem
%% ===== 支撑模块 =====
G[️ D-Bus System
• Message Bus
• PolicyKit]:::dbus
H[️ Security Modules
• SELinux/AppArmor
• D-Bus Policies]:::security
I[ Kernel Drivers
• USB CDC-ACM
• TTY Serial
• QMI WWAN]:::kernel
J[⚙️ Init Systems
• systemd (Linux)
• init (Android)]:::init
K[ Protocol Stacks
• QMI Proxy
• MBIM Handler]:::proto
%% ===== 交互流程 =====
A -->|D-Bus API| G
G -->|Method Calls| B
B -->|Plugin API| C
C -->|Socket IPC| D
D -->|JNI/Dlopen| E
E -->|Serial Protocol| K
K -->|Char Device| I
I -->|Hardware Bus| F
%% ===== 反向事件流 =====
F -->|URC| I
I -->|Data Frames| K
K -->|Parsed Events| E
E -->|RIL Unsol| D
D -->|Event Socket| C
C -->|oFono Signal| B
B -->|D-Bus Signal| G
G -->|Event Broadcast| A
%% ===== 支撑系统连接 =====
J -->|Service Start| D
J -->|Device Hotplug| I
H -->|IPC Filtering| G
H -->|Driver Access| I
%% ===== 样式定义 =====
classDef app fill:#4CAF50,stroke:#388E3C,color:white;
classDef ofono fill:#9C27B0,stroke:#6A1B9A,color:white;
classDef plugin fill:#7E57C2,stroke:#4527A0;
classDef rild fill:#FF9800,stroke:#E65100;
classDef ril fill:#F44336,stroke:#B71C1C,color:white;
classDef modem fill:#607D8B,stroke:#37474F,color:white;
classDef dbus fill:#2196F3,stroke:#0D47A1,color:white;
classDef security fill:#FF5722,stroke:#BF360C;
classDef kernel fill:#3F51B5,stroke:#1A237E,color:white;
classDef init fill:#009688,stroke:#004D40,color:white;
classDef proto fill:#00BCD4,stroke:#006064;
oFono Plugins
rilmodem
:Android RIL 适配器(核心)qmimodem
:高通 QMI 协议直连插件bluez5
:蓝牙电话网关支持cdmamodem
:CDMA 设备专用插件Kernel Drivers
USB CDC-ACM
:USB 串口抽象驱动TTY Serial
:物理串口驱动QMI WWAN
:高通设备内核级协议支持RPMSG
:SoC 内部通信驱动Protocol Stacks
QMI Proxy
:高通 MSM 接口协议处理MBIM Handler
:移动宽带接口模型解析AT Parser
:AT 命令状态机引擎Security Modules
D-Bus PolicyKit
:控制应用权限(如允许拨号)SELinux/AppArmor
:限制 RILD 访问权限串口设备权限
:/dev/ttyACM* 访问控制Init Systems
systemd
:Linux 服务管理(启动 oFono/RILD)Android init
:处理 vendor-ril 服务启动udev Rules
:自动加载 Modem 驱动Supporting Libraries
glib
:oFono 的主事件循环libqmi
:QMI 协议编码/解码库libmbim
:MBIM 协议处理库模块类型 | 解决的问题 | 典型案例 |
---|---|---|
协议适配层 | 不同 Modem 的协议差异 | QMI/MBIM/AT 转换到 RIL |
内核抽象 | 硬件访问标准化 | USB 串口 ↔ TTY 设备抽象 |
安全沙盒 | 防止非法访问 Modem | 限制 Dialer 以外的应用拨号 |
热插拔管理 | 动态处理 USB Modem 插拔 | udev 自动加载 RILD |
多协议支持 | 扩展非蜂窝网络通信能力 | 蓝牙电话网关(bluez5) |
设计哲学:通过模块化实现 “硬件可替换” 和 “功能可扩展”
- 更换 Modem 芯片时:只需修改
vendor-ril
+内核驱动
- 增加新功能(如5G):在
协议栈
层扩展,保持上层接口不变- 支持新设备类型(如卫星通信):开发新
oFono Plugin
这些模块共同构建了灵活可扩展的移动通信架构,既满足硬件多样性需求,又为应用层提供统一接口。