RILD主要起到承上启下的作用,作为modem和RILJ的通信的中转站。RILD可分为两部分,一是负责与RILJ通讯的部分,主要通过socket通信;另一个是负责与modem交互,主要通过AT指令。
在整个指令的传递过程中,主要是事件Event的传递。RIL的Event管理体系中存在3个链表结构:watch_table,timer_list,pending_list,并使用了一个设备句柄池readFDS,把所有的Socket管道的文件句柄保存起来。
与RILJ通信的部分是libril,与负责与modem交互的是厂商自己定制的reference。libril部分主要是在/hardware/ril/libril/
rild.c是libril与reference相互关联的入口,在这里libril获取到了func的指针,而reference获取到了s_rilEnv的指针,当上层有指令通过RILJ下发给libril的时候,就可以调用reference的func去传递上层命令给底层,而当底层有请求响应或者自主上报的响应的时候,便可以通过reference调用s_rilEnv指针,来上报给上层。
@rild.c
main(){int main(int argc, char **argv) {
#define REFERENCE_RIL_PATH "libreference-ril.so"
switchUser();
//打开链接库
dlHandle = dlopen(rilLibPath, RTLD_NOW);
//开启EventLoop循环
RIL_startEventLoop();
//从链接库中(也就是reference-ril.c)寻找RIL_Init函数地址
rilInit =
(const RIL_RadioFunctions *(*)(const struct RIL_Env *, int, char **))
dlsym(dlHandle, "RIL_Init");
//调用reference-ril.c中的RIL_Init函数进行初始化INIT,同时得到reference-ril的回调函数
//将s_rilEnv全局变量传递给了reference
funcs = rilInit(&s_rilEnv, argc, rilArgv);
RLOGD("RIL_Init rilInit completed");
//注册funcs
RIL_register(funcs);
RLOGD("RIL_Init RIL_register completed");
}
RIL_startEventLoop主要是处理Event事件的执行条件,事件需要放到pending_list才会被执行,watch_table和timer_list的都会以不同的方式将Event放入到pengding_list中
@ril.cpp
RIL_startEventLoop(void) {
//开启eventloop循环
int result = pthread_create(&s_tid_dispatch, &attr, eventLoop, NULL);
}
static void *
eventLoop(void *param) {
//事件初始化
ril_event_init();
ret = pipe(filedes);
s_fdWakeupRead = filedes[0];
s_fdWakeupWrite = filedes[1];
fcntl(s_fdWakeupRead, F_SETFL, O_NONBLOCK);
//创建一个event
ril_event_set (&s_wakeupfd_event, s_fdWakeupRead, true,
processWakeupCallback, NULL);
//将上面创建的event添加到watch_table中
rilEventAddWakeup (&s_wakeupfd_event);
// Only returns on error
ril_event_loop();
return NULL;
}
@ril_event.cpp
void ril_event_loop()
{
int n;
fd_set rfds;
struct timeval tv;
struct timeval * ptv;
//用for循环监测事件
for (;;) {
// make local copy of read fd_set
memcpy(&rfds, &readFds, sizeof(fd_set));
if (-1 == calcNextTimeout(&tv)) {
// no pending timers; block indefinitely
dlog("~~~~ no timers; blocking indefinitely ~~~~");
ptv = NULL;
} else {
dlog("~~~~ blocking for %ds + %dus ~~~~", (int)tv.tv_sec, (int)tv.tv_usec);
ptv = &tv;
}
printReadies(&rfds);
//用select扫描所有rfds的管道集合,检测RILJ是否有新数据产生,如果有新数据来就去遍历watch_table和timer_list
n = select(nfds, &rfds, NULL, NULL, ptv);
//检测超时事件,如果超时,把event加入到pending_list中
// Check for timeouts
processTimeouts();
//检测watch_table,将事件加入到pending_list
// Check for read-ready
processReadReadies(&rfds, n);
//执行pending_list中的event
// Fire away
firePending();
}
}
static void processTimeouts()
{
dlog("~~~~ +processTimeouts ~~~~");
MUTEX_ACQUIRE();
struct timeval now;
struct ril_event * tev = timer_list.next;
struct ril_event * next;
getNow(&now);
// walk list, see if now >= ev->timeout for any events
dlog("~~~~ Looking for timers <= %ds + %dus ~~~~", (int)now.tv_sec, (int)now.tv_usec);
while ((tev != &timer_list) && (timercmp(&now, &tev->timeout, >))) {//如果event超时,进入循环
// Timer expired
dlog("~~~~ firing timer ~~~~");
next = tev->next;
//从timer_list把事件删除
removeFromList(tev);
//将事件添加到pending_list中
addToList(tev, &pending_list);
tev = next;
}
MUTEX_RELEASE();
dlog("~~~~ -processTimeouts ~~~~");
}
//将watch_table中的事件全部取出,添加到pending_list中
static void processReadReadies(fd_set * rfds, int n)
{
dlog("~~~~ +processReadReadies (%d) ~~~~", n);
MUTEX_ACQUIRE();
for (int i = 0; (i < MAX_FD_EVENTS) && (n > 0); i++) {
struct ril_event * rev = watch_table[i];
if (rev != NULL && FD_ISSET(rev->fd, rfds)) {
addToList(rev, &pending_list);
if (rev->persist == false) {
removeWatch(rev, i);
}
n--;
}
}
MUTEX_RELEASE();
dlog("~~~~ -processReadReadies (%d) ~~~~", n);
}
//调用func方法处理event
static void firePending()
{
dlog("~~~~ +firePending ~~~~");
struct ril_event * ev = pending_list.next;
while (ev != &pending_list) {
struct ril_event * next = ev->next;
removeFromList(ev);
ev->func(ev->fd, 0, ev->param);
ev = next;
}
dlog("~~~~ -firePending ~~~~");
}