没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
试读
14页
Android的Radio Interface Layer (RIL)提供了电话服务和的radio硬件之间的抽象层。 Radio Interface Layer RIL(Radio Interface Layer)负责数据的可靠传输、AT命令的发送以及response的解析。应用处理器通过AT命令集与带GPRS功能的无线通讯模块通信。 AT command由Hayes公司发明,是一个调制解调器制造商采用的一个调制解调器命令语言,每条命令以字母"AT"开头。
资源推荐
资源详情
资源评论
Android 通信模块
第一部分 电话功能概述
Android 的 Radio Interface Layer (RIL)提供了电话服务和的 radio 硬件之间的抽象层。
Radio Interface Layer RIL(Radio Interface Layer)负责数据的可靠传输、AT 命令的发送以及
response 的解析。应用处理器通过 AT 命令集与带 GPRS 功能的无线通讯模块通信。
AT command 由 Hayes 公司发明,是一个调制解调器制造商采用的一个调制解调器命令语言,每条
命令以字母"AT"开头。
JAVA Framework
代码的路径为:
frameworks/base/telephony/java/android/telephony
android.telephony 以及 android.telephony.gsm
Corenative:
在 hardware/ril 目录中,提供了对 RIL 支持的本地代码,包括 4 个文件夹:
hardware/ril/include
hardware/ril/libril
hardware/ril/reference-ril
hardware/ril/rild
kernel Driver
在 Linux 内核的驱动中,提供了相关的驱动程序的支持,可以建立在 UART 或者 SDIO,USB 等高速
的串行总线上。
第二部分 电话功能各个部分
hardware/ril/include/telephony/目录中的 ril.h 文件是 ril 部分的基础头文件。
其中定义的结构体 RIL_RadioFunctions 如下所示:
typedef struct {
int version;
RIL_RequestFunc onRequest;
RIL_RadioStateRequest onStateRequest;
RIL_Supports supports;
RIL_Cancel onCancel;
RIL_GetVersion getVersion;
} RIL_RadioFunctions;
RIL_RadioFunctions 中包含了几个函数指针的结构体,这实际上是一个移植层的接口,下层的库实
现后,由 rild 守护进程得到这些函数指针,执行对应的函数。
几个函数指针的原型为:
typedef void (*RIL_RequestFunc) (int request, void *data,
size_t datalen, RIL_Token t);
typedef RIL_RadioState (*RIL_RadioStateRequest)();
typedef int (*RIL_Supports)(int requestCode);
typedef void (*RIL_Cancel)(RIL_Token t);
typedef const char * (*RIL_GetVersion) (void);
其中最为重要的函数是 onRequest(),它是一个请求执行的函数。
2.1 rild 守护进程
rild 守护进程的文件包含在 hardware/ril/rild
目录中,其中包含了 rild.c 和 radiooptions.c 两个文
件,这个目录中的文件经过编译后生成一个可执行程序,这个程序在系统的安装路径在:
/system/bin/rild
rild.c 是这个守护进程的入口,它具有一个主函数的入口 main,执行的过程是将请求转换成 AT 命令
的字符串,给下层的硬件执行。在运行过程 中,使用 dlopen 打开路径为/system/lib/中名称为
libreference-ril.so 的动态库,然后从中取出 RIL_Init 符号来运行。
RIL_Init 符号是一个函数指针,执行这个函数后,返回的是一个 RIL_RadioFunctions 类型的指针。
得到这个指针后,调用 RIL_register()函数,将这个指针注册到 libril 库之中,然后进入循环。
事实上,这个守护进程提供了一个申请处理的框架,而具体的功能都是在 libril.so 和 libreference-
ril.so 中完成的。
2.2 libreference-ril.so 动态库
libreference-ril.so 动态库的路径是:
hardware/ril/reference-ril
其中主要的文件是 reference-ril.c 和 atchannel.c。这个库必须实现的是一个名称为 RIL_Init 的函数,
这个函数执行的结果是返回一个 RIL_RadioFunctions 结构体的指针,指针指向函数指针。
这个库在执行的过程中需要创建一个线程来执行实际的功能。在执行的过程中,这个库将打开一个/dev/
ttySXXX 的终端(终端的名字是从上层传入的),然后利用这个终端控制硬件执行。
2.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 结构体注
册到这个库之中,在恰当的时候调用相应的函数。在执行的过程中, 这个库处理了一些将请求转换成字
符串的功能。
1. ITelephony 接口和 ISms 接口以及 AIDL
在我们的 Android 应用中,当需要实现电话拨号时,我们需要进行如下调用
ITelephony phone =
(ITelephony)ITelephony.Stub.asInterface(ServiceManager.getService("phon"))
phone.dial("10086");
对于短信应用,我们需要的是调用 SmsManager,代码如下
SmsManager manager = SmsManager.getDefault();
manager.sendTextMessage("10086",null,"hi,this is sms",null,null);
这里,SmsManager 对 ISms 做了一层包装,实质上是通过调用
ISms simISms = ISms.Stub.asInterface(ServiceManager.getService("isms"));
simISms.sendRawPdu....
可以看到,应用都是采用 AIDL 来实现 IPC 的跨进程调度。
对于 AIDL 应用,调用进程方存在的是一个实现接口的 Proxy 对象,通过 Proxy 对象与被调用进程中
的 Stub 对象进行
通讯来实现 IPC 的跨进程调度,所以,在被调用进程一端必定有一个 ITelephony.Stub 类以及
ISms.Stub 类的实现
如下图所示
2. PhoneInterfaceManager 和 SimSmsInterfaceManager
ITelephony.Stub 的实现类为 com.android.phone.PhoneInterfaceManager
ISms.Stub 的实现类为 com.android.internal.telephony.gsm.SimSmsInterfaceManager
从这两个类的构造器的调用代码里可以很清楚的看到进行了 Service 的注册工作
ServiceManager.addService("phone",this);
ServiceManager.addService("isms",this);
3. PhoneApp,InCallScreen,PhoneUtils 及其他相关类
从 SimSmsInteferManager 的相关方法实现中可以看到,具体就是调用 GSMPhone 的
SmsDispatcher 实例来进行相关操作的。
从 PhoneInterfaceManager 会维持一个 Phone 对象的引用,当拨号应用时,
PhoneInterfaceManager 会将构造好的 Intent 传递
给 PhoneApp 应用,该 Intent 的 className 指定则为 InCallScreen,从中我们可以看到 InCallScreen
具体是通过 PhoneUtils 调用 Phone 的
相关方法来实现。
PhoneInterfaceManager 怎么获取到对应的 Phone 对象,然后又怎么将 Phone 对象传递到
InCallScreen 中呢?
具体这里涉及到了 PhoneApp 这个类,从这个类维护了一个 PhoneInterfaceManager 的引用
(phoneMgr)以及一个 Phone 引用(phone),
从该类的 onCreate 方法中我们可以清楚的看到,PhoneApp 通过 PhoneFactory 获取了一个 Phone 实
例,并通过该实例实现了 PhoneInterfaceManager 对象。
因此,我们现在只需要关注 PhoneFactory 具体提供的是一个什么样的 Phone 实例了。
另外,PhoneApp 类还提供了一个静态方法 getInstance 供 InCallScreen 调用,InCallScreen 正是
通过调用该方法获得 PhoneApp 实例从而
获得对应的 Phone 实例的。
接下来,我们通过查看 PhoneFactory 的方法可以看到,Phone 对象对应的就是一个 GSMPhone 实
例。对应的 UML 类图结构如下
4。GSMPhone 与 RIL
从 GSM 的构造器可以看出,他依赖一个 CommandInterface 接口实例,通过 PhoneFactory 的
makeDefaultPhones 方法,我们可以看到,根据系统环境变量
ro.radio.noril 来判断是否需要采用 RIL 框架实现,如果该参数不为空,则采用 Simultedcommands
(主要是为了测试需要提供的模拟实现).否则,采用 RIL。
通过 Google 才知道,RIL 其实是智能手机上实现 AP 与 BP 之间通信的一种设计思想,具体大家可以
参见这篇文章 http://www.eetchina.com/ARTICLES/2006OCT/PDF/
CPCOL_2006OCT26_EMB_TA_170.PDF?SOURCES=DOWNLOAD
剩余13页未读,继续阅读
资源评论
- meteorly2012-09-12不错的东东,要是能有一些示例就完美了
- 预测天意2013-09-06不错的东东,要是能有一些示例就完美了
- huanyingjun2012-08-15很好的资料 不过缺少一些实例
dufeng02
- 粉丝: 13
- 资源: 11
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功