一、RILC主要代码目录结构
$workdir
|_hardware
|_ril
|_ CleanSpec.mk // 编译文件
|_ include // 关键头文件目录,包括ril.h、ril_cdma_sms.h等头文件
|_ libril // LibRIL Runtime运行环境的源文件目录
|_ librilutils
|_ reference-ril // RIL Stub实现源码文件目录
|_ rild // 守护进程源码文件目录
重点关注libril、reference-ril和rild这3个目录中的C/C++代码文件。
二、RILC运行机制
{RILC使用HAL Stub的运行结构,其中最关键的为Runtime对外提供Proxy代理接口,Stub向Runtime提供Operations操作函数,Runtime向Stub提供Callback函数}
RILC运行机制主要围绕 LibRIL与Reference-RIL相互调用,从而完成Solicited和UnSolicited消息的处理,其运行结构如下图所示:
RILC运行机制中包括两个过程:启动过程和运行过程。从上图中可以看出图中的步骤1,2,3可体现出RILC启动控制过程都是由rild完成的;而以LibRIL与Reference-RIL为中心的RIL消息交互的过程和方式,正是RILC中的核心运行机制。
- 启动过程
RILC加载入口:
找到$workdir/system/core/rootdir/init.rc中与RILC启动相关的配置信息,发现在Android Linux内核加载过程中,会执行rild可执行文件启动ril-daemon的系统Service服务
RILC加载方法:
找到$workdir/hardware/ril/rild/rild.c程序文件中的main函数,其中的处理逻辑最关键的是RI_startEventLoop RIL_Init和RIL_register这3个函数的调用。调用详情如下:
// 第一步,调用ril.cpp中的RIL_startEventLoop函数,LibRIL开始循环监听Socket事件
RIL_startEventLoop();
// 通过reference-ril.so动态链接库,获取指向RIL-Init函数的指针rilInit
rilInit = (const RIL_RadioFunctions *(*) (const struct RIL_Env *, int, char **)) dlsym(dlHandle, "RIL_Init");
if (rilInit == NULL) { //指向RIL_Init函数的指针rilInit异常处理
fprintf(stderr, "RIL_Init not defined or exported in %s\n", rilLIbPath);
exit(-1); // 直接退出
}
// 第二步,调用reference-ril.so动态链接库的RIL_Init函数,传递s_rilEnv给reference-ril.so,并返回funcs
funcs = rilInit(&s_rilEnv, argc, rilArgv);
// 第三步,调用libril.so的RIL_register函数,将funcs传递给libril.so
RIL_register(funcs);
调用RIL_Init函数,这里非常关键,首先通过dlsym方法获取指向reference-ril.so动态链接库中的RIL_Init函数的指针;其次,调用reference-ril.so动态链接库中的RIL-Init函数,完成RIL stub