1.Android RIL 概念
Android RIL是基于telephony 服务和raido 硬件层的抽象层, 通过研究RIL的代码可以看到,Android的rild库是介于HAL接口与baseband modem之间,它同样提供了语音、数据、短信、SIM卡管理以及STK应用的功能,实现思路跟微软的RIL有异曲同工之妙,也是把标准的 GSM27.007中常用的如dial这些做主动请求的操作称之为request,一共75个;另外一类GSM模块主动上报的例如信号强度、基站信息等, 称之为unsolicited response,一共17个;开发模式也是跟微软RIL开发差不多,需要针对不同的GSM模块进行不同的GSM驱动开发,公用的部分google给你做 好了,特定的部分需要你自己去定制,这样做可以大大地提高开发效率。 以下是RIL 交互图
2.本地代码 :
RIL 支持的本地代码包括 ril 库和守护进程:
hardware/ril/include
hardware/ril/libril
hardware/ril/rild
hardware/ril/reference-ril
编译结果是
/system/bin/rild :守护进程
/system/lib/libril.so : RIL 的库
/system/lib/libreference-ril.so : RIL 参考库
3.RIL Initialization
Android initializes the telephony stack and the Vendor RIL at startup as described in the sequence below:
(1). RIL daemon reads rild.lib path and rild.libargs system properties to determine the Vendor RIL library to use and any initialization arguments to provide to the Vendor RIL
(2). RIL daemon loads the Vendor RIL library and calls RIL_Init to initialize the RIL and obtain a reference to RIL functions
(3). RIL daemon calls RIL_register on the Android telephony stack, providing a reference to the Vendor RIL functions
See the RIL Daemon source code at //device/commands/rild/rild.c for details.
4.rild 执行流程
rild 是一个守护进程,在这里宏 RIL_SHLIB 被定义。执行的过程为:
获取参数 -> 打开功能库 -> 建立事件循环(线程) -> 执行 RIL_Init ->RIL_register 。
int main(int argc, char **argv) { /* 获取参数并解析 */ dlHandle = dlopen(rilLibPath, RTLD_NOW); /* 启动线程,进入事件循环 */ RIL_startEventLoop(); rilInit = (const RIL_RadioFunctions *(*)(const struct RIL_Env *, int, char **)) dlsym(dlHandle, "RIL_Init"); /* 处理参数 */ funcs = rilInit(&s_rilEnv, argc, rilArgv); RIL_register(funcs); done: while(1) { sleep(0x00ffffff); } }
5.RIL Interaction
RIL有两种执行流程储:
(1)Solicited commands: 基于RIL lib, 例如 DIAL and HANGUP.
(2)Unsolicited responses: 基于 baseband, 例如 CALL_STATE_CHANGED和 NEW_SMS.
5.1 Solicited
以下两段代码是请求类接口:
void OnRequest (int request_id, void *data, size_t datalen, RIL_Token t);
void OnRequestComplete (RIL_Token t, RIL_Error e, void *response, size_t responselen);
The following diagram illustrates a solicited call in Android.
5.RIL Interaction
RIL有两种执行流程储:
(1)Solicited commands: 基于RIL lib, 例如 DIAL and HANGUP.
(2)Unsolicited responses: 基于 baseband, 例如 CALL_STATE_CHANGED和 NEW_SMS.
5.1 Solicited
以下两段代码是请求类接口:
void OnRequest (int request_id, void *data, size_t datalen, RIL_Token t);
void OnRequestComplete (RIL_Token t, RIL_Error e, void *response, size_t responselen);
The following diagram illustrates a solicited call in Android.
6.RIL_Init
使用自定义的RIL lib 时,由于rild通过符号RIL_Init获取一组函数指针并以此与之建立联系 ,因而必须实现RIL_Init 函数,,RIL_Init 的定义如下:
RIL_RadioFunctions *RIL_Init (RIL_Env* env, int argc, char **argv);
RIL_Init should return a RIL_RadioFunctions structure containing the handles to the radio functions:
type structure {
int RIL_version;
RIL_RequestFunc onRequest;
RIL_RadioStateRequest onStateRequest;
RIL_Supports supports;
RIL_Cancel onCancel;
RIL_GetVersion getVersion;
}
RIL_RadioFunctions;
7.接下来分析初始化流程
主入口是rild.c中的main函数,主要完成三个任务:
(1). 开启libril.so中的event机制, 在RIL_startEventLoop中,是最核心的由多路I/O驱动的消息循环。
(2). 初始化librefrence_ril.so,也就是跟硬件或模拟硬件modem通信的部分(后面统一称硬件), 通过RIL_Init函数完成。
(3). 通过RIL_Init获取一组函数指针RIL_RadioFunctions, 并通过RIL_register完成注册,并打开接受上层命令的socket通道。
8.RIL跟上层通讯主要采用两种方式:
(1)一种是通过Socket发送与接收消息的方式来实现,
C方面,这个Socket在ril.cpp里面可以找到它的创建代码:
s_fdListen = android_get_control_socket(SOCKET_NAME_RIL);
JAVA方面,在RIL.java中:
s = new LocalSocket();
l = new LocalSocketAddress(SOCKET_NAME_RIL,
LocalSocketAddress.Namespace.RESERVED);
s.connect(l);
(2)还有另外一种方式就是直接通过TCP/IP直接访问内核中的shared memory,进行RPC调用,这种方式主要应用在数据模式上,一来由于Android的每个Activity随时都会有可能需要网络连接接收发送数据, 因此必须提供一种实时性较高访问的方式,二来可以提高通讯效率。