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()。 后文会详细分析这些流程。