当前位置:首页 > Android中RIL层详细分析解析
RIL_startEventLoop()方法所提供的功能就是启用eventLoop线程,开始执行RIL消息队列。 RIL_register()方法的主要功能是启动名为rild 的监听端口,等待java 端通过socket进行连接。
5.3 libril.so动态库
libril.so库的目录是: hardware/ril/libril
其中主要的文件为ril.cpp,这个库主要需要实现的以下几个接口为: RIL_startEventLoop(void);
void RIL_setcallbacks (const RIL_RadioFunctions *callbacks); RIL_register (const RIL_RadioFunctions *callbacks);
RIL_onRequestComplete(RIL_Token t, RIL_Errno e, void *response, size_t responselen); void RIL_onUnsolicitedResponse(int unsolResponse, void *data, size_t datalen);
RIL_requestTimedCallback (RIL_TimedCallback callback, void *param, const struct timeval *relativeTime);
这些函数也是被rild守护进程调用的,不同的vendor可以通过自己的方式实现这几个接口,这样可以保证RIL可以在不同系统的移植。其中 RIL_register()函数把外部的RIL_RadioFunctions结构体注册到这个库之中,在恰当的时候调用相应的函数。在执行的过程中,这个库处理了一些将请求转换成字符串的功能。 附:
Android自带的VendorRIL的参考实现。被编译成.so文件,由于本部分是厂商定制的重点所在。所以被设计为松散耦合,且可灵活配置的。在rild中通过opendl()的方式加载。
librefrence.so负责直接与radio通信,这包括将来自libril的指令转换为AT指令,并且将AT指令写入radio中。
reference-ril会接收调用者传来的参数,参数内容为与radio的通信方式。如通过串口连接radio,那么参数为这种形式:-d /dev/ttySx
5.4 ril层的所有代码分析
5.4.1 ril/rild下的文件 rild.c->mian()为函数入口
int main(int argc, char **argv) { // .... //
OpenLib: #endif
switchUser();
//打开dlopen()加载vendor RIL 获取由RIL_register(funcs);注册进来的参数,并解析 dlHandle = dlopen(rilLibPath, RTLD_NOW); if (dlHandle == NULL) {
fprintf(stderr, \ exit(-1); }
//1:消息队列的入口1.到select阻塞//每当看到打印信息,不按顺序打下来说明阻塞 RIL_startEventLoop();
//通过dlsym函数得到rilInit函数指针的引用
rilInit = (const RIL_RadioFunctions *(*)(const struct RIL_Env *, int, char **))dlsym(dlHandle, \
if (rilInit == NULL) {
fprintf(stderr, \ exit(-1); }
if (hasLibArgs) {
rilArgv = argv + i - 1; argc = argc -i + 1; } else {
static char * newArgv[MAX_LIB_ARGS]; static char args[PROPERTY_VALUE_MAX]; rilArgv = newArgv;
property_get(LIB_ARGS_PROPERTY, args, \ argc = make_argv(args, rilArgv); }
// Make sure there's a reasonable argv[0] rilArgv[0] = argv[0];
//2:利用得到的rilInit函数指针,调用真正的RIL_Init funcs = rilInit(&s_rilEnv, argc, rilArgv);
RIL_register(funcs); done:
while(1) {
// sleep(UINT32_MAX) seems to return immediately on bionic sleep(0x00ffffff); }
5.4.2 ril/libril->ril.cpp中RIL_startEventLoop()函数分析 RIL_startEventLoop(void) {
int ret;
pthread_attr_t attr;
LOGD(\
/* spin up eventLoop thread and wait for it to get started */ s_started = 0;
pthread_mutex_lock(&s_startupMutex); pthread_attr_init (&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
LOGD(\ ret = pthread_create(&s_tid_dispatch, &attr,eventLoop, NULL);//创建线程,为入口函数 LOGD(\ while (s_started == 0) {
pthread_cond_wait(&s_startupCond, &s_startupMutex); }
pthread_mutex_unlock(&s_startupMutex); if (ret < 0) {
LOGE(\ return; } }
---------------------------------------------------------
eventLoop(void *param) {
1.---ril_event_init();//初始化 void ril_event_init() {
MUTEX_INIT();
LOGD(\ FD_ZERO(&readFds); init_list(&timer_list); init_list(&pending_list);
memset(watch_table, 0, sizeof(watch_table)); }
2.--- ret = pipe(filedes);
3.---ril_event_set (&s_wakeupfd_event, s_fdWakeupRead, true,processWakeupCallback, NULL);
在ril/libril/ril_event.cpp实现
void ril_event_set(struct ril_event * ev, int fd, bool persist, ril_event_cb func, void * param) {
LOGD(\ril_event_set(struct ril_event * ev, int fd, bool persist, ril_event_cb func, void * param)-\
dlog(\ memset(ev, 0, sizeof(struct ril_event));
ev->fd = fd; ev->index = -1;
ev->persist = persist; ev->func = func; ev->param = param;
fcntl(fd, F_SETFL, O_NONBLOCK); }
3.1processWakeupCallback
static void processWakeupCallback(int fd, short flags, void *param) { char buff[16]; int ret;
LOGD(\read(s_fdWakeupRead, sizeof(buff));---\
LOGV(\/* empty our wakeup socket out */ do {
ret = read(s_fdWakeupRead, &buff, sizeof(buff)); } while (ret > 0 || (ret < 0 && errno == EINTR)); }
4.---rilEventAddWakeup (&s_wakeupfd_event);
static void rilEventAddWakeup(struct ril_event *ev) {
LOGD(\ril_event_add(ev);---\ ril_event_add(ev);
LOGD(\ triggerEvLoop(); }
&buff,
4.1---void ril_event_add(struct ril_event * ev) 在ril/libril/ril_event.cpp实现 {
LOGD(\ dlog(\ MUTEX_ACQUIRE();
for (int i = 0; i < MAX_FD_EVLL) { //1:
watch_table[i] = ev;//把上面ril_event_add函数添加的事件_wakeupfd_event结构体添加到这个数组来 ev->index = i;
dlog(\ dump_event(ev); //2:
FD_SET(ev->fd, &readFds);
共分享92篇相关文档