三、 ReaderLooper()
ReaderLooper主要用来监听Modem上发信息
RIL需要加载一个AT相关的reference-ril.so的动态链接库。之所以使用 库的形式,就是考虑到每个厂商使用的Modem不同,我们没法用统一的接口去向底层负责,因此使用库的形式。这样一来,不同的Modem厂商提供不同的链接库,只要符合RIL层的框架即可。
3.1 ReadLoop预备知识
3.1.1 ReferenceRIL初始化入口
前面在RILC层函数入口提到RILD会加载reference库来初始化ReferenceRIL,如下:
rilInit = (const RIL_RadioFunctions *(*)(const struct RIL_Env *, int, char **))
dlsym(dlHandle, "RIL_Init");
funcs = rilInit(&s_rilEnv, argc, rilArgv);
我们来看看:
第一行为从库为加载RIL_Init函数。
第二行有很值得分析的地方,主要有三点:
1. 执行rilInit()函数(即RIL_Init)创建ReadLoop,这点在后面会详细讨论。
2. s_rilEnv,这是一个包含LibRIL回调函数的结构体,将其传入ReferenceRL后,使得ReferenceRIL能够调用LibRIL的函数向其通信。
3. funcs,这是一个包含ReferenceRIL回调函数的结构体,其从ReferenceRIL返回给LibRIL,使得LibRIL能够调用ReferenceRIL的函数向其通信。
如上2,3点使得LibRIL和ReferenceRIL都拥有对方的回调,从而能够是他们之间进行双向通信。
下面来看看这两个包含回调函数的结构体。
3.1.2 LibRIL回调(RIL_Env)
其结构体定义为:
//@mtk_ril.h
struct RIL_Env {
/**
* "t" is parameter passed in on previous call to RIL_Notification
* routine.
*
* If "e" != SUCCESS, then response can be null/is ignored
*
* "response" is owned by caller, and should not be modified or
* freed by callee
*
* RIL_onRequestComplete will return as soon as possible
*/
void (*OnRequestComplete)(RIL_Token t, RIL_Errno e,
void *response, size_t responselen);
#if defined(ANDROID_MULTI_SIM)
/**
* "unsolResponse" is one of RIL_UNSOL_RESPONSE_*
* "data" is pointer to data defined for that RIL_UNSOL_RESPONSE_*
*
* "data" is owned by caller, and should not be modified or freed by callee
*/
void (*OnUnsolicitedResponse)(int unsolResponse, const void *data, size_t datalen, RIL_SOCKET_ID socket_id);
#else
/**
* "unsolResponse" is one of RIL_UNSOL_RESPONSE_*
* "data" is pointer to data defined for that RIL_UNSOL_RESPONSE_*
*
* "data" is owned by caller, and should not be modified or freed by callee
*/
void (*OnUnsolicitedResponse)(int unsolResponse, const void *data, size_t datalen);
#endif
/**
* Call user-specifed "callback" function on on the same thread that
* RIL_RequestFunc is called. If "relativeTime" is specified, then it specifies
* a relative time value at which the callback is invoked. If relativeTime is
* NULL or points to a 0-filled structure, the callback will be invoked as
* soon as possible
*/
void (*RequestTimedCallback) (RIL_TimedCallback callback,
void *param, const struct timeval *relativeTime);
/**
* "t" is parameter passed in on previous call RIL_Notification routine
*
* RIL_onRequestAck will be called by vendor when an Async RIL request was received
* by them and an ack needs to be sent back to java ril.
*/
void (*OnRequestAck) (RIL_Token t);
#if defined(MTK_RIL) || defined(C2K_RIL)
/**
* Same propose as RequestTimedCallback but executed in proxy thread
*/
void