RIL-Java在本质上就是一个RIL代理,起到一个转发的作用,是Android Java概念空间中的电话系统的起点。

在RIL-D的分析中,我们知道RILD建立了一个侦听套接口,等待RIL-Java的连接。一旦连接成功,RIL-JAVA就可发起一个请求,并等待应答,并将结构发送到目标处理对象。在RIL-Java中,这个请求称为RILRequest。为了直观起见,我还是不厌其烦的给出RIL-Java的框架图。

RIL-Java的大框架包含了四个方面:

Receiver,Sender,CommandInterface,异步通知机制

(1) Command Interface

在ril.java源代码中,我们可以看到RIL-JAVA对象提供了如下的Command Interface:

getlccCardStatus

getCurrrentCalls

dial

acceptCall

rejectCall

sendDTMF

sendSMS

setupDataCall

setRadioPower

为什么要定义这些接口呢?这函数接口不是凭空捏造出来的,这些都是电话的基本功能的描述,是对Modem AT指令的提炼抽象。大多数Modem都是根据通讯协议提供接口,我们如果不熟悉通讯协议,请参阅3GPP的相关文档,以及自己使用的Modem的SPEC说明。

V.25ter AT Commands

3GPP 07.07 AT Comamnds-General commands

3GPP 07.07 AT Comamnds-Call Control commans

3GPP 07.07 AT Comamnds-Network Service related commands

3GPP 07.07 AT Comamnds-MT control and status command

3GPP 07.07 AT Comamnds-GPRS Commands

3GPP 07.07 Mobile Termination Errors

3GPP 07.05 SMS AT Commands

(2)Receiver

Receiver连接到RILD的服务套接口,接收读取RILD传递过来的Response Parcel。Response分为两种类型,一种是URC,一种是命令应答。对于URC将会直接分发到通知注册表中的Handler。而命令应答则通过Receiver的异步通知机制传递到命令的发送者进行相应处理。

(3)Sender

Sender应该分为两部分架构,

上层函数调用Command Interface将请求消息发送到Sender的架构。

Sender接收到EVENT_SEND消息后,将请求发送到RILD的架构。

(4)异步应答框架

对于异步应答来讲,命令的发起者发送后,并不等待应答就返回,应答的回应是异步的,处理结果通过消息的方式返回。站在设计者的角度思考如何设计合适的框架来完成异步通讯的功能呢?对于异步系统我们首先应该考虑的是如何标识命令和结果,让命令和结果有一个对应关系,还有命令没有响应了,如何管理命令超时?让我们来看看Android设计者如何完成这些工作。

Android设计者利用了Result Message 和RILRequest对象来完成Request和Result的对应对于关系。在上层做调用的时候生成Result Message对象传递到ril_java,并在Modem有应答后,通过Result Message对象带回结果。如何保证该应答是该RILRequest的呢?Android设计者还提供了一个Token(令牌)的概念。在源代码中RILRequest的mSerail就用作了Token。Token用来唯一标识每次发送的请求,并且Token将被传递到RILD,RILD在组装应答是将Token写入,并传回到ril-java,ril-java根据该Token找到相应的Request对象。

(4.1)RIL命令的发送模式

协议的真正实现是在rild中,RIL-JAVA更多的是一个抽象和代理,我们在研究源代码的过程中就会体会到到RIL-JAVA中的命令函数都有一个共同的框架。

SendXxxCmd(传入参数Data,传出参数result){

组合RILRequest(请求号,result,mSerail)

Data->RR

send(RILRequest): Message

}

1)RILRequest

请求号:

request将传递到RILD用以标识命令,request代表某个功能。例如拨叫的request号为:RIL_REQUEST_DIAL。在libs/telephony/ril_commands.h有定义。RILRequest.obtain@RILRequest根据命令请求号,传入参数Result Message,mSerail构造了一个RILRequest。Result Message将带回应答信息回到命令的发起者。

mSerail:

Android使用了一个RILRequest对象池来管理Andoird RILRequest。mSerail是一个递增的变量,用来唯一标识一个RILRequest。在发送时正是用了该变量为Token,在rild层看到的token就是该mSerail。

EVENT_END:

EVENT_END@handleMessage@RILSender@RIL.java

2)发送步骤:

第一步:

生成RILRequest,此时将生成m_Serial(请求的Token)并将请求号,数据,及其Result Message 对象填入到RILRequest中

第二步:

使用send将RILRequest打包到EVENT_SEND消息中发送到到RIL Sender Handler,

第三步:

RilSender 接收到EVENT_SEND消息,将RILRequest通过套接口发送到RILD,同时将RILRequest保存在mRequest中以便应答消息的返回。

(4.2) 接收模式

第一步:分析接收到的Parcel,根据类型不同进行处理。

第二步:根据数据中的Token(mSerail),反查mRequest,找到对应的请求信息。

第三步:将是数据转换成结果数据。

第四步:将结果放在RequestMessage中发回到请求的发起者。

4.3)详细的GSMCallTracker,RIL-Java函数对照

GSMCallTracker在本质上是一个Handler。

GSMCallTracker是Android的通话管理层。GSMCallTracker建立了ConnectionList来管理现行的通话连接,并向上层提供电话调用接口。

在GSMCallTracker中维护着通话列表:connections。顺序记录了正连接上的通话,这些通话包括:ACTIVE,DIALING,ALERTING,HOLDING,INCOMING,WAITING等状态的连接。GSMCallTracker将这些连接分为了三类别进行管理:

RingingCall: INCOMING ,WAITING

ForegourndCall: ACTIVE, DIALING ,ALERTING

BackgroundCall: HOLDING

上层函数通过getRingCall(),getForegrouandCall()等来获得电话系统中特定通话连接。

为了管理电话状态,GSMCallTracker在构造时就将自己登记到了电话状态变化通知表中。RIL-Java一收到电话状态变化的通知,就会使用EVENT_CALL_STATE_CHANGE通知到GSMCallTacker

在一般的实现中,我们的通话Call Table是通过AT+CLCC查询到的,CPI可以通知到电话的改变,但是CPI在各个Modem的实现中差别比较大,所以参考设计都没有用到CPI这样的电话连接改变通知,而是使用最为传统的CLCC查询CALL TABLE。在GSMTracker中使用connections来管理Android电话系统中的通话连接。每次电话状态发生变化是GSMTracker就会使用CLCC查询来更新connections内容,如果内容有发生变化,则向上层发起电话状态改变的通知。

1 RIL-JAVA中发起电话连接列表操作

在RIL-JAVA中涉及到CurrentCallList查询的有以下几个操作:

(1)hangup

(2)dial

(3)acceptCall

(4)rejectCall

在GSMcallTracker在发起这些调用的时候都有一个共同的ResultMessage构造函数:obtainCompleteMessage()。obtainCompleteMessage()实际上是调用:

obtainCompleteMessage(EVENT_OPERATION_COMPLETE)

这就意味着在这些电话操作后,GSMCallTracker会收到EVENT_OPERATION_COMPLETE消息,于是我们将目光转移到handleMessage()@GSMCallTracker的EVENT_OPERATION_COMPLETE事件处理:operationComplete@GSMCallTracker。

operationComplete()操作会使用cm.getCurrentCalls(lastRelevantPoll)调用,向RILD发起RIL_REQUEST_GET_CURRENT_CALLS调用,这个最终就是向Modem发起AT+CLCC,获取到真正的电话列表。

2 在RILD中,引起getCurrentCalls调用

(1)在RILD中,收到URC消息:

+CRING

RING

NO CARRIER

+CCWA

将会使用RIL_onUnsolicitedResponse( RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED),主动向ril-java上报RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED消息。

(2) 在处理requestCurrentCalls时,使用CLCC查询通话连接(CALL TABLE)后,如何发现有call Table不为空则开启一个定时器,主动上报RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED消息,直到没有电话连接为止。

在RIL-Java层收到RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED这个URC,并利用mCallStateRegistrants.notifyRegistrants(new AsyncResult(null, null, null))来通知电话状态的变化,此时GSMTracker会接收到EVENT_CALL_STATE_CHANGE消息,并使用

pollCallsWhenSafe()->  cm.getCurrentCalls(lastRelevantPoll);

来发起查询,并更新JAVA层的电话列表。

3 handlePollCalls电话列表刷新

首先我们来看看是什么引起了handlePollCalls的调用。

上面的1,2分析了,Android电话系统中所有引起电话连接列表更新的条件及其处理。他们共同的调用了cm.getCurrentCalls(lastRelevantPoll) 来完成电话列表的获取。

lastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT)

我们这里就从可以看到获取到的电话列表Result使用handlePollCalls进行了处理。Result实际上是一个DriverCall列表,handlePollCalls的工作就是将当前电话列表与RIL-Java的电话列表对比,使用DriverCall列表更新CallTracker的电话列表connections,并向上传递电话状态改变的通知。

Android RIL Java相关推荐

  1. android ril.java_Android RIL的java框架

    Android RIL的Java部分也被分为了两个模块,RIL模块与Phone模块.其中RIL模块负责进行请求以及相应的处理,它将直接与RIL的原声代码进行通信.而Phone模块则向应用程序开发者提供 ...

  2. ril.java源码_RIL 重构  |  Android 开源项目  |  Android Open Source Project

    Android 7.0 通过一组功能对无线接口层 (RIL) 进行了重构,从而改进了 RIL 的功能.要实现这些功能,合作伙伴需要对代码进行更改:您可以自行决定是否更改,不过我们建议您进行更改.重构更 ...

  3. Android RIL源码研究笔记 の ril (一)

    Android源码目录hardware/ril/libril中总共包含5个C/CPP文件,它们分别是ril_commands.h.ril_unsol_commands.h.ril_event.h.ri ...

  4. Android RIL

    Android RIL结构分析与移植 介绍 本文档对Android RIL部分的内容进行了介绍,其重点放在了Android RIL的原生代码部分. 包括四个主题: 1.Android RIL框架介绍 ...

  5. Android RIL 架构学习总结

    1.Android RIL 概念     (转自http://newfaction.net/2011/03/08/android-ril-structure-learning-summary.html ...

  6. Android——RIL 机制源码分析

    Android 电话系统框架介绍 在android系统中rild运行在AP上,AP上的应用通过rild发送AT指令给BP,BP接收到信息后又通过rild传送给AP.AP与BP之间有两种通信方式: 1. ...

  7. Android RIL学习

    Android RIL学习 tomorrow.cyz@gmail.com 1.Android RIL概念 Android RIL是基于telephony 服务和raido 硬件层的抽象层.Androi ...

  8. Android RIL框架分析

    1.RIL框架 RIL,Radio Interface Layer.本层为一个协议转换层,提供Android Telephony与无线通信设备之间的抽象层. Android RIL位于Telephon ...

  9. 冰枫论坛android,Android Ril 分析

    引言: 这段时间手中的工作,正好好调试一款3g modem,于是乎就分析了一下Android Ril的代码,做了些总结归纳,阅读时可以先看前后两段以及流程图,这样可能更容易把握: 知识在于分享,文档中 ...

最新文章

  1. 小雨坐地铁--[最短路分层建图+虚点]
  2. 2019年十大数据与分析技术趋势
  3. 在家办公如何提高效率?
  4. Linux学习笔记——例说makefile 综合案例
  5. 【Java文件操作(三)】递归复制文件夹内所有文件
  6. bzoj2751[HAOI2012]容易题(easy)
  7. ping得通外网,上得了QQ,游戏,却打不开网页。
  8. 行为设计模式 - 状态设计模式
  9. android:AIDL
  10. this关键字在构建错误实例时使用说明
  11. redis报错: redis.exceptions.ResponseError: value is not an integer or out of range
  12. 服务器显示A40故障码,求助大神,车子出现故障码,5053无法消除
  13. ubuntu下gstreamer解码器
  14. VUE提示Gradient has outdated direction syntax
  15. #VMware#ESXI ESXI虚拟机安装
  16. 为什么我电脑在线看黄色很慢_为什么我的电脑这么慢?
  17. 月半弯,亦真亦幻亦婉约
  18. 汇编指令-CMP、TEQ
  19. Locust:简介和基本用法
  20. 【聚宽本地数据JQData】一个命令获取全部股票全部的财务报表数据

热门文章

  1. 判断是pc还是移动浏览器
  2. 利用SW插件导出urdf文件
  3. Linux服务器EDAC CE memory read error
  4. web3.js查询和修改链上的合约数据
  5. 多方面,全访问的剖析Tomcat十大线程和四大通道
  6. 提升制造卓越性 沿着价值链管理生产流程
  7. 驱动及驱动开发的简单理解
  8. 巧用img的width和height属性进行缩图,使图片不变形
  9. C/C++ 知识总结
  10. Mac苹果电脑如何一键清理磁盘内存空间?