Android RIL总体架构介绍
更新时间:2023-08-10 05:02:01 阅读量: 工程科技 文档下载
Android RIL总体架构介绍
第一部分 电话功能概述
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
Core native:
在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结构体注册到这个库之中,在恰当的时候调用相应的函数。在执行的过程中,这个库处理了一些将请求转换成字符串的功能。
本文来自CSDN博客,转载请标明出处:
本文为御风独舞原创,转载请注明出处:/roooy,谢谢:)
当我们开始编写Android的电话应用程序的时候,如果需要进行电话拨号,可以进行如下调用:
ITelephony tpCallModule =
(ITelephony)ITelephony.Stub.asInterface(ServiceManager.getService("phon")); tpCallModule.dial("13800138000");
而对于短信的应用,我们需要调用的则是SmsManager:
SmsManager SMS = SmsManager.getDefault();
SMS.sendTextMessage("13420926323",null,"this is a test sms",null,null);
到底Android是如何跟底层GSM模块通讯的呢?我一开始就猜测是不是跟WM那样采用RIL的架构来实现,查看了google的官方文档,证实了我的猜测是正确的,Android里面的确采用了RIL架构跟底层GSM模块通讯,先看看RIL在Android里的位置吧。
Android的RIL在这里被做成一个叫做rild的库,通过一个系统环境变量ro.radio.noril是否为空来决定要不要把RIL的代码编译进内核,这点跟CE的编译方式是一样的,如果设置了该变量,将会有个"SimulateCommand"的玩意编译进内核,它可以在没有实际GSM硬件的情况下模拟部分实际硬件的指令,然后让RIL驱动提供给上层应用,如果没有设置该系统环境变量就会采用RIL。
通过研究RIL的代码可以看到,Android的rild库是介于HAL接口与baseband modem之间,它同样提供了语音、数据、短信、SIM卡管理以及STK应用的功能,实现思路跟微软的RIL有异曲同工之妙,也是把标准的GSM27.007中常用的如dial这些做主动请求的操作称之为request,一共75个;另外一类GSM模块主动上报的例如信号强度、基站信息等,称之为unsolicited response,一共17个;开发模式也是跟微软RIL开发差不多,需要针对不同的GSM模块进行不同的GSM驱动开发,公用的部分google给你做好了,特定的部分需要你自己去定制,这样做可以大大地提高开发效率。
RIL跟上层通讯主要采用两种方式,一种是通过Socket发送与接收消息的方式来实现,这个Socket在ril.cpp里面可以找到它的创建代码:
s_fdListen = android_get_control_socket(SOCKET_NAME_RIL);
还有另外一种方式就是直接通过TCP/IP直接访问内核中的shared memory,进行RPC调用,这种方式主要应用在数据模式上,一来由于Android的每个Activity随时都会有可能需要网络连接接收发送数据,因此必须提供一种实时性较高访问的方式,二来可以提高通讯效率。
其实最上层的ITelephony和SmsManager有点像WM里面的Connection Manager,呵呵,有意思,这是不是其实印证了一句话“万变不离其宗”呢?今天从大体的结构上讨论了一下Android RIL的大体架构,改天再仔细研究一下这个Android RIL的更细致入微的东西。如果大家有什么更有意思的发现,欢迎来信和我交流"gzuroy#"(把#改成@)
上次介绍了一下Android的RIL架构,我们可以把它理解为是GSM模块的驱动,这次要介绍的是Telephony这个组件,我们把它和 WinCE做对比,发现它其实就是做了CellCore做的工作,只是CellCore依然很面向过程地单纯导出SDK,然后让上层驱动调用。
Telephony由于是运行在我们的Dalvik虚拟机上面的,所以它的实现也就更面向对象化了。接下来让我们看看怎么使用这个Telephony库开发我们的电话应用。
Telephony库主要负责Android的拨打与接听电话功能,其中有两个重要的类分别是IPhone和PhoneNumberUtils是我们实现电话功能必不可少的。当我们的应用需要拨打一个号码的时候,Android默认是没有授予我们这个应用的这个权限的,因此我们必须在
AndroidManifest.xml中去打开这个权限。AndroidManifest.xml是每一个应用都需要的文件,它位于应用的根目录下,文件里描述了程序包的全局变量,包括暴露的应用组件(activities, services等等)和为每个组件的实现类,以及什么样的数据可以操作和它在什么地方运行。现在我们在<manifest>里面添加一行:
<uses-permission id="android.permission.CALL_PHONE" />
从此我们的应用就拥有了拨打电话的权限了,接下来就是建立一个IPhone类的对象,上次我已经介绍了必须要通过ServiceManager来获得,以下代码演示了如何建立一个IPhone类对象:
private static IPhone getPhoneInterface() throws DeadObjectException
{
IServiceManager sm = ServiceManagerNative.getDefault();
IPhone phoneService = IPhone.Stub.asInterface(sm.getService("phone"));
return phoneService;
}
一旦建立完了IPhone对象,即可使用call或者dail方法来拨电话了:
void call(String number)
void dial(String number)
它们之间的差别就是call是在后台进行的,一般用于数据传输(gprs,edge)的应用,而dial是会显示一个简单的拨号界面,上面预设了你的参数作为拨号的号码,如果给dial的参数传入NULL,则会调用拨号的界面显示出来。
还有一种简单的拨号方法,有仔细看Intent文档的人就会发现,对一个电话格式的网址(如href="tel: (+86)1234567890")发送出CALL_ACTION,就可以调用拨号程序对其进行拨号。这种方便的方法可以在开发我们的浏览器应用的时候,直接在浏览网页的时候正则匹配到电话号码,然后直接调用拨号程序对其拨号,很方便吧。
获取电话的属性可以通过TelephonyProperties来实现,比如SIM卡,IMEI等信息,我们可以通过调用 os.SystemProperties.put()方法传入TelephonyProperties的字段来设置对应的参数,也可以通过 os.SystemProperties.get()方法获取这些参数,以下是一些实际引用的例子:
获取本机号码,调用android.os.SystemProperties.get(PROPERTY_LINE1_NUMBER); 获取IMEI,调用android.os.SystemProperties.get(PROPERTY_IMEI);
获取运营商名字,调用
android.os.SystemProperties.get(PROPERTY_SIM_OPERATOR_ALPHA);
获取国家代码,调用
android.os.SystemProperties.get(PROPERTY_SIM_OPERATOR_ISO_COUNTRY); 获取语音信箱号码,调用哪个
android.os.SystemProperties.get(PROPERTY_LINE1_VOICE_MAIL_NUMBER);
正在阅读:
Android RIL总体架构介绍08-10
高中生入党申请书模板800字09-08
节假日安全检查05-15
班主任基本功大赛04-14
读书心得体会:让读书伴成长 - 106-29
企业战略管理本复习题及参考答案06-12
最新-岳麓版九年级世界历史上册课本课后习题答案 精品 - 图文02-28
新乡化纤厂生产实习报告10-05
Allegro笔记 - 图文03-13
飞思卡尔讲解 - 图文03-16
- 在卡伦湖捕鱼节文化论坛上的讲话
- 广州市户外广告和招牌设置规范
- 储藏室管理规定
- 盾构施工引起土体位移的空间计算方法
- 高职高考英语模拟试题及答案
- 2013年成都市中学英语教学优秀论文评选通知
- 结构力学1-几何组成分析
- 身边的侵害与保护
- 2016年山东省德州市中考化学试卷(word解析卷)
- 2013 年全国普通高等学校运动训练、民族传统体育专业单独统一招生考试《政治生活》模拟试题I
- 一日常规登记表
- “丝绸之路经济带”与中俄合作(下)
- 本特利探头说明书
- 玉溪市2015人才网教师招聘考试历年试题(一)
- 动物生物学 绪论
- 对中考数学复习五点建议
- 乌海市海南区小学英语四年级下册专项复习:连词成句
- 数据库(ER图)
- 2013届高三政治一轮复习课时训练:必修1_第3课_多彩的消费1
- 小学奥数周期问题教师版