Android 2.2 RIL hardware 部分代码简介

作者: Venus
Android源码中,hardware/ril目录中包含着RIL hardware 底层源码,该目录树如下引用部分,下面将做具体的分析:

|– CleanSpec.mk
|– include
| `– telephony
| |– ril.h
| `– ril_cdma_sms.h
|– libril
| |– Android.mk
| |– MODULE_LICENSE_APACHE2
| |– NOTICE
| |– ril.cpp
| |– ril_commands.h
| |– ril_event.cpp
| |– ril_event.h
| `– ril_unsol_commands.h
|– reference-cdma-sms
| |– Android.mk
| |– reference-cdma-sms.c
| `– reference-cdma-sms.h
|– reference-ril
| |– Android.mk
| |– MODULE_LICENSE_APACHE2
| |– NOTICE
| |– at_tok.c
| |– at_tok.h
| |– atchannel.c
| |– atchannel.h
| |– misc.c
| |– misc.h
| `– reference-ril.c
`– rild
|– Android.mk
|– MODULE_LICENSE_APACHE2
|– NOTICE
|– radiooptions.c
|– rild.c
`– rild.c~


一、目录hardware/ril/include

包含两个头文件: ril.h 和 ril_cdma_sms.h ,其中 ril.h中定义了76个如下类型的宏:RIL_REQUEST_XXX ,这些宏代表着客户进程可以向Android telephony发送的命令,包括SIM卡相关的功能,打电话,发短信,网络信号查询等。 ril_cdma_sms.h 则是针对cdma sms 的扩展时所用到的一些宏和结构体的定义。
二、目录hardware/ril/libril
该目录下代码负责与上层客户进程进行交互。在接收到客户进程命令后,调用相应函数进行处理,然后将命令响应结果传回客户进程。在收到来自网络端的事件后,也传给客户进程。
1、文件ril_commands.h:列出了telephony可以接收的命令;每个命令对应的处理函数;以及命令响应的处理函数。诸如:

{RIL_REQUEST_GET_SIM_STATUS, dispatchVoid, responseSimStatus},
    {RIL_REQUEST_ENTER_SIM_PIN, dispatchStrings, responseInts},
    {RIL_REQUEST_ENTER_SIM_PUK, dispatchStrings, responseInts},
    {RIL_REQUEST_ENTER_SIM_PIN2, dispatchStrings, responseInts},
    {RIL_REQUEST_ENTER_SIM_PUK2, dispatchStrings, responseInts},
    {RIL_REQUEST_CHANGE_SIM_PIN, dispatchStrings, responseInts},
    ... .. ..


2、文件ril_unsol_commands.h:列出了telephony可以接收的事件类型;对每个事件的处理函数;诸如:
 

{RIL_UNSOL_RESPONSE_RADIO_STATE_CHANGED, responseVoid, WAKE_PARTIAL},
    {RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED, responseVoid, WAKE_PARTIAL},
    {RIL_UNSOL_RESPONSE_NETWORK_STATE_CHANGED, responseVoid, WAKE_PARTIAL},
    {RIL_UNSOL_RESPONSE_NEW_SMS, responseString, WAKE_PARTIAL},
    {RIL_UNSOL_RESPONSE_NEW_SMS_STATUS_REPORT, responseString, WAKE_PARTIAL},
    {RIL_UNSOL_RESPONSE_NEW_SMS_ON_SIM, responseInts, WAKE_PARTIAL},
    .. . . . .


3、文件ril_event.h/cpp:处理与事件源(端口,modem等)相关的功能。ril_event_loop监视所有注册的事件源,当某事件源有数据到来时,相应事件源的回调函数被触发(firePending -> ev->func())。
4、文件ril.cpp 功能较为庞大,如下:
1)RIL_register函数:打开监听端口,接收来自客户进程的命令请求 (s_fdListen = android_get_control_socket(SOCKET_NAME_RIL);),当与某客户进程连接建立时,调用 listenCallback函数;创建一单独线程监视并处理所有事件源 (通过ril_event_loop)
2)listenCallback函数:当与客户进程连接建立时,此函数被调用。此函数接着调用processCommandsCallback处理来自客户进程的命令请求
3)processCommandsCallback函数:具体处理来自客户进程的命令请求。对每一个命令,ril_commands.h中都规定了对应的命 令处理函数(dispatchXXX),processCommandsCallback会调用这个命令处理函数进行处理。
4)dispatch系列函数:此函数接收来自客户进程的命令己相应参数,并调用onRequest进行处理。
5)RIL_onUnsolicitedResponse函数:将来自网络端的事件封装(通过调用responseXXX)后传给客户进程。
6)RIL_onRequestComplete函数:将命令的最终响应结构封装(通过调用responseXXX)后传给客户进程。
7)response系列函数:对每一个命令,都规定了一个对应的response函数来处理命令的最终响应;对每一个网络端的事件,也规定了一个对应的 response函数来处理此事件。response函数可被onUnsolicitedResponse或者onRequestComplete调用。
三、目录hardware/ril/reference-ril
本目录下代码主要负责与modem(调制解调器)进行交互。
1、文件reference-ril.c:
此文件核心是两个函数:onRequest和onUnsolicited
1) onRequest 函数:在这个函数里,对每一个RIL_REQUEST_XXX请求,都转化成相应的AT command,发送给modem,然后睡眠等待。当收到此AT command的最终响应后,线程被唤醒,将响应传给客户进程(RIL_onRequestComplete -> sendResponse)。
2) onUnsolicited函数:这个函数处理modem从网络端收到的各种事件,如网络信号变化,拨入的电话,收到短信等。然后将时间传给客户进程 (RIL_onUnsolicitedResponse -> sendResponse)。
2、文件atchannel.c:
负责向modem读写数据。其中,写数据(主要是AT command)功能运行在主线程中,读数据功能运行在一个单独的读线程中。
函数at_send_command_full_nolock:运行在主线程里面。将一个AT command命令写入modem后进入睡眠状态(使用 pthread_cond_wait或类似函数),直到modem读线程将其唤醒。唤醒后此函数获得了AT command的最终响应并返回。函数readerLoop运行在一个单独的读线程里面,负责从modem中读取数据。读到的数据可分为三种类型:网络端传入的事件;modem对当前AT command的部分响应;modem对当前AT command的全部响应。对第三种类型的数据(AT command的全部响应),读线程唤醒(pthread_cond_signal)睡眠状态的主线程。
3、文件at_tok.c 提供AT响应的解析函数
4、misc.c 字面意思杂项,里面就提供一个字符串匹配函数
四、目录hardware/ril/rild
该目录下的代码主要是为了生成rild 和 radiooptions 的可执行文件
1、radiooptions.c 生成radiooptions 的可执行文件, radooptions程序仅仅是把命令行参数传递给socket{rild-debug}去处理而已,从而达到与rild通信,可供调试时配置Modem参数。
2、rild.c 生成 rild 的可执行文件