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

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

} }

MUTEX_RELEASE();

dlog(\}

-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

static void firePending() {

LOGD(\LOGI(\

dlog(\ struct ril_event * ev = pending_list.next; while (ev != &pending_list) { struct ril_event * next = ev->next; removeFromList(ev);

ev->func(ev->fd, 0, ev->param); ev = next; }

dlog(\}

<三>--RIL层代码分析---RIL_register()

ril/rild/rild.c->main()为函数入口

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

1.消息队列select为非阻塞的去轮询事件 2.read的阻塞的去读取上层发下来的命令,并响应

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

int main(int argc, char **argv) {

const char * rilLibPath = NULL; char **rilArgv; void *dlHandle;

const RIL_RadioFunctions *(*rilInit)(const struct RIL_Env *, int, char **); const RIL_RadioFunctions *funcs;

char libPath[PROPERTY_VALUE_MAX]; unsigned char hasLibArgs = 0; ........ OpenLib: #endif

switchUser();

/*打开dlopen()函数,就会动态去加载动态库vendor RIL 获取由RIL_register(funcs);注册进来的参数,并解析*/ dlHandle = dlopen(rilLibPath, RTLD_NOW); if (dlHandle == NULL) {

fprintf(stderr, \ exit(-1); }

/*消息队列的入口,添加到select,用阻塞方式去读取那些ril_event_set()的数据##每当看到打印信息,不按顺序打下来说明阻塞##*/

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

/*利用得到的rilInit函数指针,调用真正的RIL_Init ,实际是动态加载动态库去链接reference-ril.c ,由dlopen()函数加载*/

funcs = rilInit(&s_rilEnv, argc, rilArgv);

/*RIL_register作用一:把vendor RIL(即RIL_init) 注册到reference-ril库去等待,dopen()函数加载链接

附:RIL_init通过是onRequest()方法,将上层来的请求进行映射后转换成对应的AT命令发给硬件,rild通过RIL_register注册这一指针。

RIL_register作用二:创建rild socket主要是等待java层得数据通过,传到下一层,还创建debug socket*/ RIL_register(funcs); done: while(1) {

// sleep(UINT32_MAX) seems to return immediately on bionic

sleep(0x00ffffff); }

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 所有文件:

hardware/ril/libril$ ls

Android.mk NOTICE ril_event.h ril.cpp ril_event.cpp ril_commands.h ril_unsol_commands.h --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

funcs =rilInit(&s_rilEnv, argc, rilArgv);//实际是通过动态加载动态库的方式执行reference-ril.c中的RIL_Init 由RIL_Init的返回值开始的,这是一个RIL_RadioFunctions结构的指针。 typedef struct {

int version; /* set to RIL_VERSION */ RIL_RequestFunc onRequest;

RIL_RadioStateRequest onStateRequest; RIL_Supports supports; RIL_Cancel onCancel; RIL_GetVersion getVersion; } RIL_RadioFunctions;

其中最重要的是onRequest域,上层来的请求都由这个函数进行映射后转换成对应的AT命令发给硬件。rild通过RIL_register注册这一指针。

RIL_register中要完成的另外一个任务,就是打开前面提到的跟上层通信的socket接口(s_fdListen是主接口,s_fdDebug供调试时使用)。

然后将这两个socket接口使用任务一中实现的机制进行注册(仅列出s_fdListen) ril_event_set (&s_listen_event, s_fdListen, false, listenCallback, NULL); rilEventAddWakeup (&s_listen_event);

这样将两个socket加到任务一中建立起来多路复用I/O的检查句柄集合中,一旦有上层来的(调试)请求,event机制便能响应处理了。 总结:0.监听所有socket

1.RIL_register()把ril_init()初始化后的vendor RIL注册到libril.so等待dlopen()h函数加载,调用,再后到select机制中的ril_event_loop()函数轮询

2.获取连个socket(rild socket和debug socket),而rild socket 是用来和java层通信得,debug socket是用来调试的

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

ril/libril/ril.cpp->RIL_register 函数

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

/*注册rild socket端口事件监听到事件循环中和bedug socket */

extern \

RIL_register (const RIL_RadioFunctions *callbacks) {//说明已经初始化完了 ,才回调

int ret; int flags;

LOGD(\ if (callbacks == NULL

|| ! (callbacks->version == RIL_VERSION || callbacks->version == 1) ) { LOGE(

\ \ return; }

if (s_registerCalled > 0) {

LOGE(\ \

LOGD(\ \ return; } //1:换个马甲

memcpy(&s_callbacks, callbacks, sizeof (RIL_RadioFunctions));

s_registerCalled = 1; // Little self-check

for (int i = 0; i < (int)NUM_ELEMS(s_commands); i++) { assert(i == s_commands[i].requestNumber); }

for (int i = 0; i < (int)NUM_ELEMS(s_unsolResponses); i++) { assert(i + RIL_UNSOL_RESPONSE_BASE == s_unsolResponses[i].requestNumber); }

// New rild impl calls RIL_startEventLoop() first // old standalone impl wants it here. if (s_started == 0) { RIL_startEventLoop(); }

// start listen socket 开始侦听套接字 #if 0

ret = socket_local_server

(SOCKET_NAME_RIL,ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);

if (ret < 0) {

LOGE(\ exit (-1); }

s_fdListen = ret; #else