5,RIL—>reference-ril
首先ril从socket中读取RILJ发送的数据,然后在ril进行处理封装,最后发送到reference-ril进行处理。
5.1 读取数据
读取数据流程图如下,
eventLoop方法如下,
static void *eventLoop(void *param) {
int ret;
int filedes[2];
ril_event_init();//Event的初始化
pthread_mutex_lock(&s_startupMutex);
s_started = 1;
pthread_cond_broadcast(&s_startupCond);
pthread_mutex_unlock(&s_startupMutex);
ret = pipe(filedes);//创建管道
if (ret < 0) {
RLOGE("Error in pipe() errno:%d", errno);
return NULL;
}
s_fdWakeupRead = filedes[0];
s_fdWakeupWrite = filedes[1];
fcntl(s_fdWakeupRead, F_SETFL, O_NONBLOCK); //设置管道读端属性
//利用pipe创建一个Event
ril_event_set (&s_wakeupfd_event, s_fdWakeupRead, true, processWakeupCallback, NULL);
rilEventAddWakeup (&s_wakeupfd_event);
// Only returns on error
ril_event_loop();//进入loop循环
RLOGE ("error in event_loop_base errno:%d", errno);
// kill self to restart on error
kill(0, SIGKILL);
return NULL;
}
主要分为2个步骤:
1,调用ril_event_init方法进行Event的初始化。
2,调用ril_event_loop方法进入循环。
5.1.1 Event初始化
ril_event_init方法如下,
void ril_event_init()
{
MUTEX_INIT();
FD_ZERO(&readFds);
init_list(&timer_list);
init_list(&pending_list);
memset(watch_table, 0, sizeof(watch_table));
}
对三个链表进行初始化。
5.1.2 Event循环
ril_event_loop方法如下,
void ril_event_loop()
{
int n;
fd_set rfds;
struct timeval tv;
struct timeval * ptv;
for (;;) { //死循环检测Event消息
// 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; /NULL说明select是阻塞模式
} else {
dlog("~~~~ blocking for %ds + %dus ~~~~", (int)tv.tv_sec, (int)tv.tv_usec);
ptv = &tv; //非空说明在超时时间内是阻塞模式
}
printReadies(&rfds);
//用select去扫描readFds中的所有管道集合,检测RILJ是否有新数据出现。
n = select(nfds, &rfds, NULL, NULL, ptv);
printReadies(&rfds);
dlog("~~~~ %d events fired ~~~~", n);
if (n < 0) {
if (errno == EINTR) continue;
RLOGE("ril_event: select error (%d)", errno);
// bail?
retu