Android中RIL层详细分析解析 联系客服

发布时间 : 星期三 文章Android中RIL层详细分析解析更新完毕开始阅读124fdd7c657d27284b73f242336c1eb91b37334a

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);