2.Android RIL与WindowsMobile RIL
Android RIL与WindowsMobile RIL 在设计思路上都是作为一个radio的抽象,为上层提供电话服务,但在实现方式上两者有着一定的差异,这种差异的产生主要是源自操作系统机制的不同。
Android RIL被实现为HAL,相对于windows mobile中被实现为驱动的方式,Android RIL模块的内聚性更为理想,可维护性也将更强,你也可以把Android Ril 看做一个中间件。Android RIL部分的开发工作,只需要拿到相应的radio文件描述符,就可以进行操作,无需关注radio的I/O驱动实现。
2.1两者在与应用通信上的实现对比
WindowsMobile RIL在实现与应用的通信时提供了RIL Proxy,在这个层面中它定义了大量的RIL_***()函数来作为电话服务请求。这一点与Android RIL的实现比较相似,Android RIL中在ril.h内提供了一系列的宏来定义电话服务请求。
在Android中的rild功能类似于windows mobile RIL的RIL proxy。它同样也是起到一个中介的作用,为上层接口向下传递请求,并上传回响应。在windows mobile RIL中要为每一个应用程序客户提供一份Ril Proxy实例。
对于这两种操作系统平台,RIL所定义的所有请求是不可更改的。
2.2两者在线程结构与回调机制上的对比
在windows mobile的设计中,request与response被设计为异步执行的,他们分别使用两个队列来对它们的异步行为进行管理,执行命令下发和上报命令处理的过程也互不影响,下发命令与命令的相应响应之间的依赖关系由应用程序来捏合。
在android ril中的request与response设计与windows mobile不同,它的命令与响应之间是同步的过程。也就是说一条命令被下发后,将等待执行结果,并进行处理,再上向上层发。而不是直接异步的进行处理和向上发送。
3.Android RIL porting
3.1.命名
要实现某个无线模块的RIL,需要创建一个实现了所有请求方法的共享库,保证Android能够响应无线通信请求。所有的请求被定义ril.h中。
不同的Modem使用不同的端口,这个在init.rc中设置。
Android提供了一个参考Vendor RIL,RIL参考源码在reference-ril。
将你自己的Vendor RIL实现编译为共享库形式:
比如:
3.2.Android RIL的配置与加载
在init.rc文件中,将通过这种方式来进行Android RIL的加载。
service ril-daemon /system/bin/rild -l /system/lib/libreference-ril.so -- -d /dev/ttyS0
也可以手动加载:
/system/bin/rild -l /system/lib/libreference-ril.so -- -d /dev/ttyS0
这两种方式,都将启动rild守护进程,然后通过-l参数将libreference-ril.so共享库链入,libreference-ril.so的参数-d是指加载一个串口设备,/dev/ttyS0则是这个串口设备的具体设备文件,除了参数-d外,还有-s代表加载类型为socket的设备,-p代表回环接口。
3.3.Android RIL的编译结构
rild:
被编译成可执行文件,rild以守进程的形式执行。
libril:
将被编译为共享库,并被链入rild。
Vendor RIL:
可以以两种方式来运行,如果定义了RIL_SHLIB宏,那么它将被编译成共享库,如果没定义RIL_SHLIB宏,它将以守护进程程序的方式被调用执行。
4.Android RIL的java框架
Android RIL的Java部分也被分为了两个模块,RIL模块与Phone模块。其中RIL模块负责进行请求以及相应的处理,它将直接与RIL的原声代码进行通信。而Phone模块则向应用程序开发者提供了一系列的电话功能接口。
4.1.RIL模块结构
在RIL.java中实现了几个类来进行与下层rild的通信。
它实现了如下几个类来完成操作:
RILRequest:代表一个命令请求
RIL.RILSender:负责AT指令的发送
RIL.RILReceiver:用于处理主动和普通上报信息
RIL.RILSender与RIL.RILReceiver是两个线程。
RILRequest提供了obtain()方法,用于得到具体的request操作,这些操作被定义在RILConstants.java中(RILConstants.java中定义的request命令与RIL原生代码中ril.h中定义的request命令是相同的),然后通过send()函数发送EVENT_SEND,在RIL_Sender线程中处理这个EVENT_SEND将命令写入到stream(socket)中去。Socket是来自常量SOCKET_NAME_RIL,它与RIL原生代码部分的s_fdListen所指的socket是同一个。
当有上报信息来到时,系统将通过RILReciver来得到信息,并进行处理。在RILReciver的生命周期里,它一直监视着SOCKET_NAME_RIL这个socket,当有数据到来时,它将通过readRilMessage()方法读取到一个完整的响应,然后通过processResponse来进行处理。
4.2.Phone模块结构
Android通过暴露Phone模块来供上层应用程序用户使用电话功能相关的接口。它为用户提供了诸如电话呼叫,短信息,SIM卡管理之类的接口调用。它的核心部分是类GSMPhone,这个是Gsm的电话实现,需要通过PhoneFactory获取这个GSMPhone。
GSMPhone并不是直接提供接口给上层用户使用,而是通过另外一个管理类TelephonyManager来供应用程序用户使用。
类TelephonyManager实现了android的电话相关操作。它主要使用两个服务来访问telephony功能:
1.ITelephony,提供给上层应用程序用户与telephony进行操作,交互的接口,在packages/apps/Phone中由PhoneInterfaceManager.java实现。
2.ItelephonyRegistry提供了一个通知机制,将底层来的上报通知给框架中需要得到通知的部分,由TelephonyRegistry.java实现。
GSMPhone通过PhoneNotifier的实现者DefaultPhoneNotifier将具体的事件转化为函数调用,通知到TelephonyRegistry。TelephonyRegistry再通过两种方式通知给用户,其一是广播事件,另外一种是通过服务用户在TelephonyRegistry中注册的IphoneStateListener接口,实现回调(回调方式参见android的aidl机制)。
参考资料
相关网站:
http://code.google.com/android/
http://www.ibm.com/developerworks/cn/opensource/theme/android/
http://en.wikipedia.org/wiki/Android_(operating_system)