Android设置了RIL层,是上层framework与Modem沟通的桥梁。高通使用qcril作为其vendor-RIL,与modem之间使用QMI机制通讯。
分3篇分析下面的问题:
- RIL如何启动及初始化?
- RILJ和RILD如何关联?
- RILJ的消息如何传递和被处理?
- event table的定义
- event如何管理
- event的处理、返回结果和主动上报(UNSOL)
- 如何正确地添加一个RIL消息和对应的处理函数?
RILD进程启动
RIL、QCRIL运行在RILD进程,在开机后启动,Rild.c的main函数为入口:
/system/core/rootdir/init.rc
service netd /system/bin/netd
class main
socket netd stream 0660 root system
socket dnsproxyd stream 0660 root inet
socket mdns stream 0660 root system
socket fwmarkd stream 0660 root inet
RILD2
/device/qcom/common/rootdir/etc/init.qcom.rc
service ril-daemon2 /system/bin/rild -c 2
class main
socket rild2 stream 660 root radio
socket rild-debug2 stream 660 radio system
user root
disabled
group radio cache inet misc audio sdcard_r sdcard_rw qcom_diag diag log
rild主函数入口:
#define LIB_PATH_PROPERTY "rild.libpath"
int main(int argc, char **argv) {
const char * rilLibPath = NULL;
if (rilLibPath == NULL) {
//这里的property值为:vendor/lib64/libril-qc-qmi-1.so
if ( 0 == property_get(LIB_PATH_PROPERTY, libPath, NULL)) {
// No lib sepcified on the command line, and nothing set in props.
// Assume "no-ril" case.
goto done;
} else {
rilLibPath = libPath;
}
}
//获取libril-qc-qmi-1.so库的句柄
dlHandle = dlopen(rilLibPath, RTLD_NOW);
if (dlHandle == NULL) {
RLOGE("dlopen failed: %s", dlerror());
exit(EXIT_FAILURE);
}
RIL_startEventLoop();
//获取RIL_Init函数指针
rilInit = (const RIL_RadioFunctions *(*)(const struct RIL_Env *, int, char **))
dlsym(dlHandle, "RIL_Init");
//调用RIL_Init函数,s_rilEnv定义见后面
funcs = rilInit(&s_rilEnv, argc, rilArgv);
RLOGD("RIL_Init rilInit completed");
RIL_register(funcs);
}
//提供给qcril的回调函数,消息处理完成后调用这些callback函数返回
static struct RIL_Env s_rilEnv = {
RIL_onRequestComplete,
RIL_onUnsolicitedResponse,
RIL_requestTimedCallback
};
RILD入口主要关注这3个函数:
RIL_startEventLoop() —— ril.cpp,线程中开启一个消息循环来监听消息并触发事件处理。
RIL_Init() —— qcril.c初始化工作
RIL_register() —— 注册qcril.c消息函数入口(ril与qcril的关联)
RIL_startEventLoop()
int main(int argc, char **argv) {
RIL_startEventLoop();
}
ril.cpp
extern "C" void
RIL_startEventLoop(void) {
/* spin up eventLoop thread and wait for it to get started */
s_started = 0;
pthread_mutex_lock(&s_startupMutex);
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
//创建线程,负责执行eventLoop函数
int result = pthread_create(&s_tid_dispatch, &attr, eventLoop, NULL);
if (result != 0) {
RLOGE("Failed to create dispatch thread: %s", strerror(result));
goto done;
}
while (s_started == 0) {
pthread_cond_wait(&s_startupCond, &s_startupMutex);
}
done:
pthread_mutex_unlock(&s_startupMutex);
}
RIL_startEventLoop(v