综述
RILJ属于系统Phone进程的一部分,随Phone进程启动而加载;而RILD守护进程是通过Android的Init进程进行加载的。
RIL的设计目的,是为上层应用开发者,提供一个通用服务接口,使应用开发者专注于应用功能的实现,而屏蔽掉不同radio实现间的细节差异;同时,RIL也提供通用的下层移植接口,使采用了RIL架构的产品平台可方便地在不同的radio之间移植。
RIL结构
下图是一个Android RIL的一个结构图。整个通信过程有4层:
最上层的是APP,如通话,短信及SIM卡管理,它们主要负责将用户的指令发送到RIL Framework(以后统称RILJ);
RILJ为上层提供了通用的API,如TelephonyManager(包括通话,网络状态; SubscriptionManager(卡状态)及SmsManager等,同时RILJ还负责维持与RILD的通信,并将上层的请求发送给RILD;
RILJ
负责将上层APP的通信请求发送给HAL层;
RILJ的代码按照功能来划分的话,主要由以下几个组成部分:
管理网络状态(信号强度,网络注册状态等):ServiceStateTracker等;
通话管理(拨号,接听,呼叫等待等): CallManager,GsmCallTracker等
SMS短信接收发送: InboundSMSHandler,SmsDispater等
SIM卡管理: UiccController, SubscriptionsController等
数据链接管理: DcTracker,DctController等
Telephony 大管家: PhoneBase,GsmPhone,PhoneProxy等
RILD
运行在AP上,它是AP和BP在软件层面上通信的中枢,即,AP上的APP将通过Rild发送AT指令给BP,而BP的信息通过Rild传送给AP上的APP。
solicited Response:AP向BP发消息,BP回复
unsolicited Response:BP发送通知给AP
libril.so
和rild结合得比较紧密,是其共享库,在编译时就确定了这种关系,主要文件为ril.cpp、ril_event.cpp,主要负责同上层的通信工作,接收ril请求并传递给librefrence_ril.so,同时将librefrence_ril.so返回的消息送给调用进程。
librefrence.so
通过dlopen方式加载,与rild结合不是很紧密,主要负责跟Modem硬件通信,它转换来自libril.so的请求为AT命令,同时监听Modem的反馈信息,并传回libril.so,这种运行时加载的方式可很方便地修改参数来适配不同的Modem。
与底层Modem通信的主要工作是在文件librefrence_ril.so中完成的,librefrence_ril.so的主要代码为Reference-ril.c
RIL Request
每一個 telephony command 在 RILD 中稱為一個 RIL request,每個 RIL request 都是透過 integer 來代表,google定義的 request 從 0開始,MediaTek新增的request 會從 2000 開始,所有request 均定義在alps/hardware/ril/include/telephony/ril.h
Request Table
由於Java與Native是透過socket來傳遞資料,所以當傳遞RIL request時,也必須定義調用的函式需要的參數以及回傳值,Google已經定義了許多的dispatch function以及response type,所以需要維護一個request的table來記錄每個request的運行方式,在table中的定義順序必須與request ID一致,此table維護在alps/mediatek/hardware/ril/librilmtk/Ril_commands.h,
原生 Google 定義的 RIL request 調用定義範例
Dispatch Function
Execute a Request
Handle response data of RIL Request
RIL Request Logging
Summary
URC
每個 URC 均都有一個 integer 來代表,其中 MediaTek 新增的 URC 會從 3000 開始,均定義在alps/hardware/ril/include/telephony/ril.h
URC Table
由於Java與Native是透過 socket來傳遞資料,URC必須定義URC 的data type以及手機 power wake lock的 type,Google 已經定義了許多的 data type 以及 power wake lock type,所以需要維護一個 request 的table 來記錄每個 URC 的運行方式,此 table 維護在
alps/mediatek/hardware/ril/librilmtk/Ril_unsol_commands.h
URC flow
URC 來源是 modem URC channel 上報上來的 AT command,由ATChannels.c readLoop 來讀取並判斷是否為 URC,當為 URC 時透過調用 onUnsolicited 來進入 URC flow,onUnsolicited 會調用所有的 function Unsolicited 函式來進一步分析 URC string 並轉為 socket response