background image

1. 开启 libril.so 中的 event 机制, 在 RIL_startEventLoop 中,是最核心的由多路 I/O 驱

动的消息循环。

2. 初始化 librefrence_ril.so,也就是跟硬件或模拟硬件 modem 通信的部分(后面统一称

硬件),

 通过 RIL_Init 函数完成。

3. 通过 RIL_Init 获取一组函数指针 RIL_RadioFunctions, 并通过 RIL_register 完成注册,

并打开接受上层命令的

socket 通道。

首先看第一个任务,也就是

RIL_startEventLoop 函数。RIL_startEventLoop 在 ril.cpp 中

实现,

 它的主要目的是通过 pthread_create(&s_tid_dispatch, &attr, eventLoop, NULL)建立一

dispatch 线 程 , 入 口 点 在 eventLoop.  而 eventLoop 中 , 会 调 ril_event.cpp 中 的

ril_event_loop()函数,建立起消息(event)队列机制。

我们来仔细看看这一消息队列的机制,这些代码都在

ril_event.cpp 中。

void ril_event_init();
void ril_event_set(struct ril_event * ev, int fd, bool persist, ril_event_cb func, void * param);
void ril_event_add(struct ril_event * ev);
void ril_timer_add(struct ril_event * ev, struct timeval * tv);
void ril_event_del(struct ril_event * ev);
void ril_event_loop();

struct ril_event {
   struct ril_event *next;
   struct ril_event *prev;

int fd;
   int index;
   bool persist;
   struct timeval timeout;
   ril_event_cb func;
   void *param;
};

每个

ril_event 结构,与一个 fd 句柄绑定(可以是文件,socket,管道等),并且带一

func 指针去执行指定的操作。

具体流程是:

 ril_event_init 完成后,通过 ril_event_set 来配置一新 ril_event,并通过

ril_event_add 加入队列之中(实际通常用 rilEventAddWakeup 来添加),add 会把队列里所

ril_event 的 fd,放入一个 fd 集合 readFds 中。这样 ril_event_loop 能通过一个多路复用 I/O

的 机 制 (

select ) 来 等 待 这 些 fd ,   如 果 任 何 一 个 fd 有 数 据 写 入 , 则 进 入 分 析 流 程

processTimeouts(),processReadReadies(&rfds, n),firePending()。 后文会详细分析这些流程。