一.整体架构综述
ril用于实现打电话,发短信等通信业务功能,它主要通过AT命令与硬件模块交互实现功能。
这里一共涉及两个进程,一个是Phone process,一个是ril进程,Phone显然是上层进程,ril是负责与硬件打交道的进程。在ril中有四个线程,rild启动了一个主线程和一个eventLoop线程,主线程一直处于休眠状态,eventLoop线程在接收到Phone进程的命令之后,会调用ril.so的api函数发送request,这个request实际上就是AT command,也就是说eventLoop线程是发送AT command的线程。ril.so也启动了两个线程,一个是mainLoop线程,一个是readerLoop,mainLoop线程主要用于启动和恢复readerLoop线程,readerLoop线程则用于读取AT command的响应。下面将详细分析ril的实现。
二.rild
hardware/ril/rild/rild.c
main函数
-----> 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);
该函数主要是载入so文件,然后调用so文件的RIL_Init函数,该函数的作用是使得rild和so文件互相注册回调函数,它把RIL_Env注册给so,同时返回RIL_RadioFunctions,使得rild得到一组函数指针,RIL_RadioFunctions和RIL_Env的结构如下:
//so文件交给ril调用的api
typedef struct {
int version; /* set to RIL_VERSION */
RIL_RequestFunc onRequest;
RIL_RadioStateRequest onStateRequest;
RIL_Supports supports;
RIL_Cancel onCancel;
RIL_GetVersion getVersion;
} RIL_RadioFunctions;
//ril交给so文件调用的callback函数,用于通知某个事件
struct RIL_Env {
void (*OnRequestComplete)(RIL_Token t, RIL_Errno e,
void *response, size_t responselen);
void (*OnUnsolicitedResponse)(int unsolResponse, const void *data,
size_t datalen);
void (*RequestTimedCallback) (RIL_TimedCallback callback,
void *param, const struct timeval *relativeTime);
};
static struct RIL_Env s_rilEnv = {
RIL_onRequestComplete,
RIL_onUnsolicitedResponse,
RIL_requestTimedCallback
};
RIL_startEventLoop函数
hardware/ril/libril/ril.cpp
RIL_startEventLoop(void)该函数启动eventLoop进程
--->eventLoop(void *param)
-----> ril_event_init();
-----> ret = pipe(filedes);
-----> s_fdWakeupRead = filedes[0];
s_fdWakeupWrite = filedes[1];
----->ril_event_set (&s_wakeupfd_event, s_fdWakeupRead, true,processWakeupCallback, NULL);
rilEventAddWakeup (&s_wakeupfd_event);
-------->void ril_event_add(struct ril_event * ev) //add event to watch_table and rfds read set
-------->static void triggerEvLoop()
----------->void ril_event_loop()
for (;;) {
----->calcNextTimeout//获取timer_list第
hardware/ril/rild/rild.c
main函数
-----> 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);
该函数主要是载入so文件,然后调用so文件的RIL_Init函数,该函数的作用是使得rild和so文件互相注册回调函数,它把RIL_Env注册给so,同时返回RIL_RadioFunctions,使得rild得到一组函数指针,RIL_RadioFunctions和RIL_Env的结构如下:
//so文件交给ril调用的api
typedef struct {
int version; /* set to RIL_VERSION */
RIL_RequestFunc onRequest;
RIL_RadioStateRequest onStateRequest;
RIL_Supports supports;
RIL_Cancel onCancel;
RIL_GetVersion getVersion;
} RIL_RadioFunctions;
//ril交给so文件调用的callback函数,用于通知某个事件
struct RIL_Env {
void (*OnRequestComplete)(RIL_Token t, RIL_Errno e,
void *response, size_t responselen);
void (*OnUnsolicitedResponse)(int unsolResponse, const void *data,
size_t datalen);
void (*RequestTimedCallback) (RIL_TimedCallback callback,
void *param, const struct timeval *relativeTime);
};
static struct RIL_Env s_rilEnv = {
RIL_onRequestComplete,
RIL_onUnsolicitedResponse,
RIL_requestTimedCallback
};
RIL_startEventLoop函数
hardware/ril/libril/ril.cpp
RIL_startEventLoop(void)该函数启动eventLoop进程
--->eventLoop(void *param)
-----> ril_event_init();
-----> ret = pipe(filedes);
-----> s_fdWakeupRead = filedes[0];
s_fdWakeupWrite = filedes[1];
----->ril_event_set (&s_wakeupfd_event, s_fdWakeupRead, true,processWakeupCallback, NULL);
rilEventAddWakeup (&s_wakeupfd_event);
-------->void ril_event_add(struct ril_event * ev) //add event to watch_table and rfds read set
-------->static void triggerEvLoop()
----------->void ril_event_loop()
for (;;) {
----->calcNextTimeout//获取timer_list第