四、LibRIL启动注册
联通RILJ与RILC
前面ReferenceRIL的init函数参数s_rilEnv是吧LibRIL的回调传入ReferenceRIL,这样ReferenceRIL就可以向LibRIL传递数据。
而init函数的返回值返回了自己的回调函数funcs,这样LibRIL就可以向ReferenceRIL传递数据。
这一步就是把funcs放入LibRIL中。
并且进行了一些端口参数的初始化操作。
4.1 RIL_register
从RIL_register(funcs)说起,看看它都干了什么.
前面说到funcs是ReferenceRIL的回调函数。
RIL_register的实现在ril.cpp中:
RIL_register (const RIL_RadioFunctions *callbacks) {
...
//保存回调函数到本地
memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions));
//初始化Socket参数,一张SIM卡对应一个参数,此结构体详细内容见4.3
for (i = 0; i < SIM_COUNT; i++) {
s_ril_param_socket[i] = {
(RIL_SOCKET_ID)(RIL_SOCKET_1+i), /* socket_id */
-1, /* Socket监听句柄*/
-1, /* Socket流句柄 */
PHONE_PROCESS, /* processName */
&s_commands_event[i], /* Socket流处理Event*/
&s_listen_event[i], /* Socket监听Event*/
processCommandsCallback, /* Socket流处理函数*/
NULL /* p_rs */
};
}
//使用默认参数启动Socket监听
//注意这里RIL_SOCKET_1是一个枚举变量的首元素
for (i = 0; i < SIM_COUNT; i++) {
startListen((RIL_SOCKET_ID)(RIL_SOCKET_1+i), &s_ril_param_socket[i]);
}
}
static void startListen(RIL_SOCKET_ID socket_id, SocketListenParam* socket_listen_p) {
//获取socket_name对应的RILJ与RILD连接Socket
fdListen = android_get_control_socket(socket_name);
//尝试连接此Socket,成功return 0
ret = listen(fdListen, 4);
//连接失败则退出
if (ret < 0) {
exit(-1);
}
//将可以连接成功的Socket FD放入Socket参数
socket_listen_p->fdListen = fdListen;
//使用Socket FD构建Event
//注意这里persist参数为false,此Event只能被激发一次,即使用它只能传递一次数据。
//在4.3.2可以看到,在读取完一次数据之后,又会重新添加Event
ril_event_set (socket_listen_p->listen_event, fdListen, false,
listenCallback, socket_listen_p);
//将Event添加到EventLoop中
rilEventAddWakeup (socket_listen_p->listen_event);
}
从以上代码得知,RIL_register函数主要干了两件事:
1. 将ReferenceRIL的回调函数保存。
2. 建立RILJ与RILC的Socket连接(通过fdListen),并将其放到了EventLoop中。
那么结合已经启动的EventLoop机制,此时RILJ和RILC的连接已经打通。